http://www.cnblogs.com/tnspop/archive/2012/01/11/2318819.html
上一节记录了数据绑定的自定义模板,可以在显示和编辑模板中添加任意控件实现业务需求,但出现一个问题
在编辑模板中进行编辑后却没有影响数据对象.这里要讲的是绑定的三种模式OneTime,OneWay,TwoWay
OneTime模式是在数据加载的时候显示数据,不影响数据对象也不被数据对象影响
OneWay模式受数据对象的变化而变化
TwoWay模式可以影响数据对象,也可以被数据对象影响
在上一节的代码中没有指定绑定的Mode(绑定模式),即系统默认为OneWay
但这里的绑定模式对数据对象有个要求,就是它要实现INotifyPropertyChange接口,(通知属性修发)
如果数据对象没有继承该接口,则数据对象改变后不会通知数据绑定控件属性修改事件
在继承了该接口后,上述三种模式才会显示其作用
数据对象类
/// <summary> /// DataGrid自定义列 /// </summary> public class BookClass2 : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private bool _isselect; private string _title; private double _price; private string _author; private DateTime _time; private string _sendmessage; private string _entity; /// <summary> /// 是否选择 /// </summary> public bool IsSelect//DataGridCheckBoxColumn模板,模式不对其作用 { get { return _isselect; } set { _isselect = value; } } /// <summary> /// 书名 /// </summary> public string Title { get { return _title; } set { _title = value; NotifyProperty("Title"); } }//DataGridTextColumn模板,模式不对其作用 /// <summary> /// 价格 /// </summary> public double Price { get { return _price; } set { _price = value; NotifyProperty("Price"); } }//DataGridTemplateColumn模板,模式:OneWay,不改变数据对象,但受数据对象影响 /// <summary> /// 作者 /// </summary> public string Author { get { return _author; } set { _author = value; NotifyProperty("Author"); } }//DataGridTemplateColumn模板,编辑模板是ComboBox,模式:OneWay,改变数据对象用SelectionChanged事件 /// <summary> /// 发布日期 /// </summary> public DateTime Time { get { return _time; } set { _time = value; NotifyProperty("Time"); } }//DataGridTemplateColumn模板,显示模式:OneTime,只接受一次数据,不受数据对象改变影响 /// <summary> /// 给该书留言 /// </summary> public string SendMessage { get { return _sendmessage; } set { _sendmessage = value; NotifyProperty("SendMessage"); } }//DataGridTemplateColumn模板,模式:TwoWay,可以改变数据对象,也可以受数据对象影响 /// <summary> /// 作者列表 /// </summary> public List<Auth> AuthorList { get; set; }//ComboBox数据源 /// <summary> /// 简介 /// </summary> public string Entity { get { return _entity; } set { _entity = value; NotifyProperty("Entity"); } }//RowDetailsTemplate模板 /// <summary> /// 实例化 /// </summary> /// <param name="isselect">是否选择</param> /// <param name="title">书名</param> /// <param name="author">作者</param> /// <param name="entity">简介</param> /// <param name="price">价格</param> public BookClass2(bool isselect, string title, string author, string entity, double price) { IsSelect = isselect; Title = title; Author = author; Entity = entity; Time = DateTime.Now; AuthorList = Auth.List; Price = price; } #region INotifyPropertyChanged 成员 private void NotifyProperty(string name) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name)); } #endregion } /// <summary> /// 作者类 /// </summary> public class Auth { public string AuthName { get; set; } public static List<Auth> List = new List<Auth>() { new Auth { AuthName = "tnspop" }, new Auth { AuthName = "tnsstar" }, new Auth { AuthName = "tnssun" } }; }
DataGrid控件
<UserControl xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="DataGridTest.Control.DataGridBook2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="500"> <StackPanel Orientation="Vertical"> <data:DataGrid Name="gridSetColumns" AutoGenerateColumns="False"> <data:DataGrid.Columns> <data:DataGridCheckBoxColumn Header="操作" Binding="{Binding IsSelect}"/> <data:DataGridTextColumn Header="书名" Binding="{Binding Title,Mode=OneTime}"/> <data:DataGridTemplateColumn Header="价格"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Price}"/> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox Text="{Binding Price,Mode=OneWay}"/> </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn> <data:DataGridTemplateColumn Header="作者"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Author}"/> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <ComboBox ItemsSource="{Binding AuthorList}" SelectionChanged="ComboBox_SelectionChanged"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding AuthName}"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn> <data:DataGridTemplateColumn Header="给作者留言"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding SendMessage}"/> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox Text="{Binding SendMessage,Mode=TwoWay}"/> </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn> <data:DataGridTemplateColumn Header="发布日期"> <data:DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Time,Mode=OneTime}"/> </DataTemplate> </data:DataGridTemplateColumn.CellTemplate> <data:DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <controls:DatePicker SelectedDate="{Binding Time,Mode=TwoWay}"></controls:DatePicker> </DataTemplate> </data:DataGridTemplateColumn.CellEditingTemplate> </data:DataGridTemplateColumn> </data:DataGrid.Columns> <data:DataGrid.RowDetailsTemplate> <DataTemplate> <TextBlock Text="{Binding Entity}"/> </DataTemplate> </data:DataGrid.RowDetailsTemplate> </data:DataGrid> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <Button Name="btnTest" Content="检测" Click="Button_Click" Width="60" Height="24" VerticalAlignment="Bottom" /> <Button Name="btnUpdate" Content="修改数据对象" Click="btnUpdate_Click" Width="60" Height="24" VerticalAlignment="Bottom" /> </StackPanel> <StackPanel Orientation="Vertical" Name="stackJC"> <CheckBox IsChecked="{Binding IsSelect}" Name="chkisselct"/> <TextBox Text="{Binding Title}" Name="txttitle"/> <TextBox Text="{Binding Price}" Name="txtprice"/> <TextBox Text="{Binding Author}" Name="txtauthor"/> <TextBox Text="{Binding SendMessage}" Name="txtsendmessage"/> <TextBox Text="{Binding Time}" Name="txttime"/> <TextBox Text="{Binding Entity}" Name="txtentity"/> </StackPanel> </StackPanel> </UserControl>
后台CS代码
public partial class DataGridBook2 : UserControl { List<BookClass2> list = new List<BookClass2>() { new BookClass2(true, "坏蛋是怎样炼成的", "tnspop","这本书讲了谢文东是如何从一个弱者变成一个强者的",12), new BookClass2(false, "咸郎平说", "tnsstar","这本书讲了一些常见的经济问题,分析的很透彻",43), new BookClass2(true, "帝国主义在中国", "tnssun","这本书讲了那些资本投资的金融学家在中国的一些见不得光的事情",26) }; BookClass2 bc; public DataGridBook2() { InitializeComponent(); Databinding(); } private void Databinding() { gridSetColumns.ItemsSource = list; } private void Button_Click(object sender, RoutedEventArgs e) { if (gridSetColumns.SelectedIndex == -1) { MessageBox.Show("请选择一行"); return; } bc = list[gridSetColumns.SelectedIndex]; stackJC.DataContext = bc; } /// <summary> /// 修改数据对象 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnUpdate_Click(object sender, RoutedEventArgs e) { if (bc == null) return; bc.IsSelect = chkisselct.IsChecked.Value; bc.Author = txtauthor.Text; bc.Entity = txtentity.Text; bc.Price = double.Parse(txtprice.Text); bc.SendMessage = txtsendmessage.Text; bc.Time = DateTime.Parse(txttime.Text); bc.Title = txttitle.Text; } private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { (gridSetColumns.SelectedItem as BookClass2).Author = ((sender as ComboBox).SelectedItem as Auth).AuthName; } }
通过这个案例,我们可以看到
Mode=OneWay,则数据对象改变则可以影响DataGrid行,DataGrid行中修改数据不会影响数据对象
Mode=OneTime,则数据对象改变不会影响DataGrid行,DataGrid行中修改数据不会影响数据对象
Mode=TwoWay,则数据对象改变可以影响DataGrid行,DataGrid行中修改数据可以影响数据对象
在你双击行的时候如果有编辑模板的话,会从数据对象中重新获取数据.