【WPF】WPF DataGrid List数据源 双向绑定通知机制之ObservableCollection使用以及MultiBinding 的应用
以下代码实现了DataGrid的简单绑定List数据源
重点要提一下的是,绑定List数据源,但是不能直接用List。比如下面的代码,使用List<GridItem>只能实现数据修改的绑定,但是数据添加,删除都无法实现双向绑定。所以这里要改用ObservableCollection<GridItem>,其他代码都不用改。只要类型改下即可,WPF内部已经实现了添加,删除等的双向绑定功能。
接下去,就直接上代码了....
1、Model
public class GridModel { public GridModel() { GridData = new ObservableCollection<GridItem>(); } public ObservableCollection<GridItem> GridData { get { return _griddata; } set { _griddata = value; } } private ObservableCollection<GridItem> _griddata; }
GridItem数据类
public class GridItem : INotifyPropertyChanged { public GridItem(string name, string sex, bool chk = false) { Name = name; Sex = sex; UserChecked = chk; } public string Name { get { return _name; } set { if (_name != value) { _name = value; OnPropertyChanged("Name"); } } } public string Sex { get { return _sex; } set { if (_sex != value) { _sex = value; OnPropertyChanged("Sex"); } } } public bool UserChecked { get { return _userchecked; } set { if (_userchecked != value) { _userchecked = value; OnPropertyChanged("UserChecked"); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private string _name; private string _sex; private bool _userchecked; }
2、ViewModel
public class GridViewModel { public GridViewModel() { GridSource = new GridModel(); GridSource.GridData.Add(new GridItem("王路飞", "男")); GridSource.GridData.Add(new GridItem("娜美", "女", true)); AddCommand = new DelegateCommand(Add, (obj) => true); DecCommand = new DelegateCommand(Dec, (obj) => true); ModifyCommand = new DelegateCommand(Modify, (obj) => true); ShowCommand = new DelegateCommand(Show, (obj) => true); } public GridModel GridSource { get; set; } public ICommand AddCommand { get; set; } public ICommand DecCommand { get; set; } public ICommand ModifyCommand { get; set; } public ICommand ShowCommand { get; set; } private void Add(object obj) { GridSource.GridData.Add(new GridItem("Luffy", "man",true)); } private void Dec(object obj) { GridSource.GridData.RemoveAt(0); } private void Modify(object obj) { GridSource.GridData[0].Name = "路飞"; GridSource.GridData[0].Sex = "女"; GridSource.GridData[0].UserChecked = true; } private void Show(object obj) { MessageBox.Show(GridSource.GridData[0].Name + "," + GridSource.GridData[0].Sex + "," + GridSource.GridData[0].UserChecked); } }
3、XMAL
<Grid> <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="27,25,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"> </TextBox> <Label x:Name="label" Content="Label" Margin="173,23,79,0" VerticalAlignment="Top"/> <Label x:Name="label1" Content="Label" Margin="233,23,19,0" VerticalAlignment="Top"/> <DataGrid x:Name="dataGrid" Margin="16,71,19,44" ItemsSource="{Binding GridSource.GridData}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTemplateColumn Header="选中" Width="40"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox IsChecked="{Binding UserChecked, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></CheckBox> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Header="用户名" Width="80" Binding="{Binding Name, Mode=TwoWay}"/> <DataGridTextColumn Header="用户性别" Width="80" Binding="{Binding Sex, Mode=TwoWay}"/> </DataGrid.Columns> </DataGrid> <Button x:Name="button" Content="添加" Command="{Binding AddCommand}" HorizontalAlignment="Left" Margin="16,0,0,5" Width="53" Height="29" VerticalAlignment="Bottom"/> <Button x:Name="button_Copy" Content="删除" Command="{Binding DecCommand}" HorizontalAlignment="Left" Margin="83,0,0,5" Width="53" Height="29" VerticalAlignment="Bottom"/> <Button x:Name="button_Copy1" Content="修改" Command="{Binding ModifyCommand}" HorizontalAlignment="Left" Margin="151,0,0,5" Width="53" Height="29" VerticalAlignment="Bottom"/> <Button x:Name="button_Copy2" Content="显示" Command="{Binding ShowCommand}" HorizontalAlignment="Left" Margin="220,0,0,5" Width="53" Height="29" VerticalAlignment="Bottom"/> </Grid>
4、后台代码
this.DataContext = new ViewModel.GridViewModel();
功能补充:一个文本框绑定2个属性X+Y形式
1、XMAL修改,主要是绑定使用MultiBinding (红色是新增的)
<Window x:Class="AddMessage.BindingTest" 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:AddMessage" xmlns:localmodel="clr-namespace:AddMessage.Model" mc:Ignorable="d" Title="BindingTest" Height="300" Width="300" WindowStartupLocation="CenterScreen"> <Window.Resources> <localmodel:TextConverter x:Key="TxtConvert"></localmodel:TextConverter> </Window.Resources> <Grid> <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="27,25,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"> <TextBox.Text> <MultiBinding Converter="{StaticResource TxtConvert}"> <Binding Path="Text" ElementName="lblleft"/> <Binding Path="Text" ElementName="lblright"/> </MultiBinding> </TextBox.Text> </TextBox> <TextBox x:Name="lblleft" Text="1" Margin="173,23,79,0" Height="25" VerticalAlignment="Top"/> <TextBox x:Name="lblright" Text="2" Margin="233,23,19,0" Height="25" VerticalAlignment="Top"/> <DataGrid x:Name="dataGrid" Margin="16,71,19,44" ItemsSource="{Binding GridSource.GridData}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTemplateColumn Header="选中" Width="40"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox IsChecked="{Binding UserChecked, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></CheckBox> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Header="用户名" Width="80" Binding="{Binding Name, Mode=TwoWay}"/> <DataGridTextColumn Header="用户性别" Width="80" Binding="{Binding Sex, Mode=TwoWay}"/> </DataGrid.Columns> </DataGrid> <Button x:Name="button" Content="添加" Command="{Binding AddCommand}" HorizontalAlignment="Left" Margin="16,0,0,5" Width="53" Height="29" VerticalAlignment="Bottom"/> <Button x:Name="button_Copy" Content="删除" Command="{Binding DecCommand}" HorizontalAlignment="Left" Margin="83,0,0,5" Width="53" Height="29" VerticalAlignment="Bottom"/> <Button x:Name="button_Copy1" Content="修改" Command="{Binding ModifyCommand}" HorizontalAlignment="Left" Margin="151,0,0,5" Width="53" Height="29" VerticalAlignment="Bottom"/> <Button x:Name="button_Copy2" Content="显示" Command="{Binding ShowCommand}" HorizontalAlignment="Left" Margin="220,0,0,5" Width="53" Height="29" VerticalAlignment="Bottom"/> </Grid> </Window>
2、TextConverter 格式转换类,即处理,将2个文本合并成一个文本
public class TextConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { string val = ""; foreach (var v in values) { if (val == "") val = v.ToString(); else val += "+" + v; } return val; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { string val = value.ToString(); string[] vals = val.Split('+'); return vals; } }