dip*_*016 4 c# wpf xaml binding datagrid
我无法将List绑定到DataGrid.它应该尽可能简单.我是WPF的新手,这是我的个人教育.
我有一个View(编辑器),ViewModel(VMText)和一个Data(JustText)类.
我的来源到目前为止:
JustText.cs
namespace Model
{
public class Text
{
private string _code;
public string Code
{
get { return _code; }
set { _code = value; }
}
public Text()
{
_code = "Hello World!\nHow you doin'?";
}
}
}
Run Code Online (Sandbox Code Playgroud)
VMText.cs
namespace ViewModel
{
public class VMText
{
private Model.Text _code;
public List<string> Code
{
get { return new List<string>(_code.Code.Split('\n')); }
set { _code.Code = System.String.Join("\n", value.ToArray()); }
}
private View.Editor editor;
public VMText(View.Editor editor)
{
_code = new Model.Text();
this.editor = editor;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Editor.xaml
<Window x:Class="View.Editor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:View"
mc:Ignorable="d"
Title="Editor" Height="240.024" Width="269.895">
<Grid Background="#FF292929" Margin="0,0,-6.8,0.4">
<DataGrid x:Name="dataGrid"
HorizontalAlignment="Left"
Margin="0,0,0,0"
VerticalAlignment="Top"
Width="200pt"
Height="100pt"
DataContext="{Binding vmText}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Code, UpdateSourceTrigger=PropertyChanged}" Foreground="Black" Width="60" Header="Test" IsReadOnly="false" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
Editor.xaml.cs
namespace View
{
public partial class Editor : Window
{
private ViewModel.VMText vmText;
#region Constructor
public Editor()
{
InitializeComponent();
vmText = new ViewModel.VMText(this);
DataContext = vmText;
}
#endregion
}
}
Run Code Online (Sandbox Code Playgroud)
我只想在DataGrid的一列中显示在VMText中创建的List
如果您真的想使用网格编辑项目Code
,则需要重写视图模型以使其成为可能.您无法为网格提供字符串集合.你必须给它一些具有字符串属性的类的集合.这就是WPF的工作方式.
如果您不想编辑它们,只需将IsReadOnly="True"
列放在列上它们将是只读的.
此外,你所有的绑定看起来都像是在随意猜测一切意味着什么.
所以这是一个如何做我认为你想做的事情的例子.我删除了你的Model.Text
课程以简化事情.如果没有它你就足够深了.
ViewModels.cs
namespace ViewModel
{
#region ViewModelBase
public class ViewModelBase : INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] String propName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
#endregion INotifyPropertyChanged
}
#endregion ViewModelBase
// This is the class we'll put in the grid.
public class CodeItem : ViewModelBase
{
private String _value = default(String);
public String Value
{
get { return _value; }
set
{
if (value != _value)
{
_value = value;
OnPropertyChanged();
}
}
}
}
public class VMText : ViewModelBase
{
public String CodeString
{
get {
return String.Join("\n", Codes.Select(ci => ci.Value));
}
set
{
var q = (value ?? "")
.Split(new[] { '\n' })
.Select(s => new CodeItem { Value = s });
Codes = new ObservableCollection<CodeItem>(q);
}
}
#region Codes Property
private ObservableCollection<CodeItem> _codes = default(ObservableCollection<CodeItem>);
public ObservableCollection<CodeItem> Codes
{
get { return _codes; }
set
{
if (value != _codes)
{
_codes = value;
OnPropertyChanged();
}
}
}
#endregion Codes Property
}
}
Run Code Online (Sandbox Code Playgroud)
MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel.VMText
{
CodeString = "Hello World!\nHow you doin'?"
};
}
Run Code Online (Sandbox Code Playgroud)
MainWindow.xaml
<!--
Heights and widths in XAML aren't expressed in "pt" units.
That's CSS. Give XAML a floating point value with no unit specified.
Added AutoGenerateColumns="False" so you don't get a clone of the column
with "Value" for a header.
-->
<DataGrid
x:Name="dataGrid"
HorizontalAlignment="Left"
Margin="0,0,0,0"
VerticalAlignment="Top"
ItemsSource="{Binding Codes}"
AutoGenerateColumns="False"
Width="200"
Height="100"
>
<DataGrid.Columns>
<!--
Removed UpdateSourceTrigger=PropertyChanged because it has no effect.
Removed IsReadOnly="false" because it's the default already.
-->
<DataGridTextColumn
Binding="{Binding Value}"
Width="120"
Header="Test"
/>
</DataGrid.Columns>
</DataGrid>
Run Code Online (Sandbox Code Playgroud)
我猜您只是想在DataGrid中的视图模型的Code source collection属性中显示字符串。
然后,您应该将DataGrid 的ItemsSource属性绑定到视图模型的Code源属性,然后将DataGridTextColumn绑定到Code列表本身中的字符串。您只需要稍微修改视图的XAML标记即可看到字符串。尝试这个:
<DataGrid x:Name="dataGrid"
HorizontalAlignment="Left"
Margin="0,0,0,0"
VerticalAlignment="Top"
Width="200pt"
Height="100pt"
ItemsSource="{Binding Code}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding}"
Foreground="Black" Width="60" Header="Test" IsReadOnly="false" />
</DataGrid.Columns>
</DataGrid>
Run Code Online (Sandbox Code Playgroud)