上一节记录了数据绑定的自定义模板,可以在显示和编辑模板中添加任意控件实现业务需求,但出现一个问题
在编辑模板中进行编辑后却没有影响数据对象.这里要讲的是绑定的三种模式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行中修改数据可以影响数据对象
在你双击行的时候如果有编辑模板的话,会从数据对象中重新获取数据.