修改Observable舰娘collection修改器更新datagrid

2025人阅读
将基于WPF框架的数据表格内的业务逻辑数据格式化是非常复杂的过程,尤其是当MSDN没有提供提供任何帮助的时候。我花了数周的时间弄清了如何正确绑定数据,下面我的讲解将会帮助你终止无尽的搜索和浪费时间。
WPF 数据表格结构&
作为容器的数据表格层次差不多就是下面这样了:
数据表(DataGrid )
行(DataGridRows)
单元格(DataGridCell)
文本块(TextBlock
一个数据表包含多个数据行,一个数据行包含多个单元格,单元格能且仅能包含一个文本块,前提是文本块是一个列文本(TextColumn)并且在只读模式下(在编辑模式下会变为文本框(TextBox))。在树形结构下,表的结构有点复杂:&&
需要注意的是,数据列不是树形结构的一部分。但是对数据列做出的任何定义将会被应用至那一列的所有单元格。
WPF 捆绑基础
捆绑将会被分配至一个FrameworkElement属性,由这个属性组成要捆绑的目标容器。
WPF捆绑需要2个参数:&&
来源:&哪个对象提供了信息?
路径:&对象下的哪个属性可以使用&?
通常情况下,来源继承自它自己父容器的数据文本(DataContext)属性。但是数据表格的此属性无法被用于捆绑行和单元格,因为每一行都需要捆绑不同的业务逻辑对象。
数据列将指定的捆绑数据呈现在每个单元格中,与对应的属性捆绑。在运行时,数据表会为每一个文本块的文本(TextBlock.Text)创建一个捆绑。不幸的是,并不是所有属性的文本块都支持被数据表捆绑。如果你想自定义文本块的格式,那么你很有可能会失败,因为捆绑操作并不知道你使用的是目标资源中的哪个业务对象。
提取业务数据
通过下面的方法获取数据:
public class StockItem {
public string Name { }
public int Quantity { }
public bool IsObsolete { }
Quantity&&
IsObsolete&&
Many items&
Enough items
Shortage item
Item with error&&
Obsolete item
在数据表和业务数据之间建立连接
难点并不在于数据表和业务数据之间连接的建立,通常我们可以用CollectionViewSource来建立此种连接。&
CollectionViewSource完成导航、排序、筛选等事项。
1) 在Windows.Resource中定义CollectionViewSource
&Window.Resources&
&CollectionViewSource x:Key=&ItemCollectionViewSource&
CollectionViewType=&ListCollectionView&/&
&/Window.Resources&
关键在于,这里你必须使用CollectionViewType。否则数据表将使用 BindingListCollectionView,而这个空间将不具备排序功能。当然,MSDN并没有在任何地方提及这个事情。
2) 设置数据表的DataContext属性和 CollectionViewSource建立连接关系。
DataContext=&{StaticResource ItemCollectionViewSource}&
ItemsSource=&{Binding}&
AutoGenerateColumns=&False&
CanUserAddRows=&False&&
3) 在下面的代码中,找到CollectionViewSource,并将业务数据指定为来源属性。
//create business data
var itemList = new List&stockitem&();
itemList.Add(new StockItem {Name= &Many items&,
Quantity=100, IsObsolete=false});
itemList.Add(new StockItem {Name= &Enough items&,
Quantity=10,
IsObsolete=false});
//link business data to CollectionViewSource
CollectionViewSource itemCollectionViewS
itemCollectionViewSource = (CollectionViewSource)(FindResource(&ItemCollectionViewSource&));
itemCollectionViewSource.Source = itemL
本文中的数据权限仅为可读。如果想让用户可以修改数据,可以使用ObservableCollection。
构建数据表&
如果仅是对整个列进行调整,只需设置数据列(DataGridColumn)中的某个属性就好了,比如字体加粗:
&DataGridTextColumn Binding=&{Binding Path=Name}& Header=&Name& FontWeight=&Bold&/&目前为止的数据捆绑还未涉及到表格的创建,仅是对内容进行编辑(例如文本块中的文本属性)。&
构建所有的行
构建行的方法比较特殊,因为涉及到很多行,所以数据表提供了RowStyle属性。对此属性进行操作将会涉及到所有的行。
&datagrid.rowstyle&
&style targettype=&DataGridRow&&
&Setter Property=&Background& Value=&{Binding RelativeSource={RelativeSource Self},
Path=Item.Quantity, Converter={StaticResource QuantityToBackgroundConverter}}&/&
&/datagrid.rowstyle&
DatGridRow 有一个&包含该行的业务逻辑对象的 Item&属性,因此&DataRow 的绑定必须绑定到它自己!有点奇怪的是 Path,因为 Item&是类型对象并且不知道任何的业务数据属性。但 WPF 绑定应用了一点魔力,无论怎样都能查找 Stock 项目的&Quantity&属性。
在这个例子中,背景(background)这一行依赖于业务对象的&Quantity 属性的值。在 stock 中如果有许多项,背景应该是白色的,如果只剩下几个,背景应该是灰色的。QuantityToBackgroundConverter 完成了必要的计算:
class QuantityToBackgroundConverter: IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
if (value is int) {
int quantity = (int)
if (quantity&=100) return Brushes.W
if (quantity&=10) return Brushes.WhiteS
if (quantity&=0) return Brushes.LightG
return Brushes.W //quantity should not be below 0
//value is not an integer. Do not throw an exception in the converter, but return something that is obviously wrong
return Brushes.Y
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotImplementedException();
格式化一个基于所显示的值的单元格
仅格式化一个单元格而不是整行是一个挑战。在文本列中,单元格有一个需要样式的 TextBlock。为 TextBlock 创建一个样式是简单的,但如何将&TextBlock 属性限制在适当的业务对象上呢?DataGrit 已经绑定到&TextBlock 的 Text 属性了。如果样式仅依赖与单元格的值,我们可以简单地对这个 Text 属性使用一个自我约束 。
例如:在我们的 stock 网格中,Quantity 应该一直大于或等于零。如果某个 quantity 是不符的,那么它将以红色显示一个错误:
&Setter Property=&Foreground&
Value=&{Binding
RelativeSource={RelativeSource Self},
Path=Text,
Converter={StaticResource QuantityToForegroundConverter}}& /&
格式化一个基于业务逻辑数据的单元格
最复杂的情况是如果单元格格式不是依赖于单元格的值,而是其他的一些业务数据。在我们的例子中,Quantity 中的某一项如果是丢弃的就应该显示为完全穿透。 为了达到这个目的,TextDecorations 属性需要链接到那一行的业务对象。这意味着 TextBlock 不得不查找父级的 DataGridRow。幸运的是,可以使用一个相对源绑定到一个父级可视对象:
public class IsObsoleteToTextDecorationsConverter: IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
if (value is bool) {
if ((bool)value) {
TextDecorationCollection redStrikthroughTextDecoration = TextDecorations.Strikethrough.CloneCurrentValue();
redStrikthroughTextDecoration[0].Pen = new Pen {Brush=Brushes.Red, Thickness = 3 };
return redStrikthroughTextD
return new TextDecorationCollection();
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotImplementedException();
请在 Zip 文件中查看样例的完整源代码。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:961462次
积分:16107
积分:16107
排名:第365名
原创:656篇
转载:14篇
译文:164篇
评论:103条
(2)(24)(3)(14)(3)(1)(2)(4)(2)(3)(2)(4)(2)(6)(6)(2)(5)(5)(4)(13)(70)(80)(64)(37)(74)(56)(11)(19)(29)(39)(62)(76)(17)(36)(9)(19)(14)(3)(4)(4)(5)wpf中,当DataGrid.ItemsSource与ObservableCollection绑定后,值变化时,DataGrid如何刷新?_百度知道
wpf中,当DataGrid.ItemsSource与ObservableCollection绑定后,值变化时,DataGrid如何刷新?
(),DataGrid显示的内容并不变化,在_zdmsgFile变化后.ItemsSource = _zdmsgFileprivate ObservableCollection&ZDMsgFile& _zdmsgFile = new ObservableCollection&ZDMsgFile&gt,调用DataGrid的什么方法能使DataGrid的显示的数据与_zdmsgFile同步;当在后台_zdmsgFile值变化时;DataGrid
提问者采纳
this.DataGrid先设置DataGrid的ItemsSource 为空.ItemsSource = _zdmsgFile,然后重新绑定.ItemsSource =this.DataGrid
提问者评价
其他类似问题
为您推荐:
wpf的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 舰娘collection更新 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信