如何将自定义列的数据上下文设置为 ItemsSource 项目类型?
Posted
技术标签:
【中文标题】如何将自定义列的数据上下文设置为 ItemsSource 项目类型?【英文标题】:How to set custom column's datacontext to ItemsSource item type? 【发布时间】:2020-12-29 20:22:47 【问题描述】:我试图了解框架的默认实现如何设法拥有 itemssource 项的数据上下文。具体来说,当设置了 DataGrid 的 ItemsSource(例如设置为 Foo 对象的集合)并且您在 DataGrid.Columns 属性中定义列时,DataGridTextColumn “Binding”属性需要来自 Foo 对象的属性。
以下代码可能更好地说明问题:
public class MainWindowViewModel
public List<Foo> Foos get;
public class Foo
public string FooDesignation get;
我非常简单的视图模型包含我的 DataGrid 的集合。然后我希望使用我自己的自定义列添加到 DataGrid 的列集合中:
public class CustomDataGridTextColumn : DataGridTextColumn
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
nameof(Text),
typeof(string),
typeof(CustomDataGridTextColumn),
new PropertyMetadata(default(string)));
public string Text
get => (string) this.GetValue(TextProperty);
set => this.SetValue(TextProperty, value);
private Binding _textBinding;
public Binding TextBinding
get => _textBinding;
set => _textBinding = value;
生成的 XAML 如下所示(在 MainWindowView 中,数据上下文设置为 MainWindowViewModel 的实例)
<d:Window.DataContext>
<x:Type Type="local:MainWindowViewModel" />
</d:Window.DataContext>
<Grid>
<DataGrid ItemsSource="Binding Foos" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="Binding FooDesignation" />
<local:CustomDataGridTextColumn Text="Binding FooDesignation" TextBinding="Binding FooDesignation" />
</DataGrid.Columns>
</DataGrid>
</Grid>
DataGridTextColumn 的 Binding 属性可以毫无问题地绑定到 Foo (FooDesignation) 的属性,intellisense 也将此属性显示为一个选项。
我自己的 CustomDataGridTextColumn 的 Text 和 TextBinding 属性在绑定到同一个 FooDesignation 属性时会显示设计时和运行时错误。 Intellisense 向我展示了我的 MainWindowViewModel 的 Foos 属性作为选项(这很有意义,因为它显然没有继承 Foo 对象数据上下文)。
我的假设是它与 DataGridTextColumn 的 Binding 属性属于 Binding 类型这一事实有关,并且被配置为以某种方式运行可以。
我无法找到/理解这是如何实现的。任何人都可以对此有所了解吗?我的目标是让 Text/*TextBinding 属性的行为与 Binding 属性相同。
【问题讨论】:
【参考方案1】:您可以将ItemsSource
设置为任何IEnumerable
,并且DataGrid
将列的绑定应用于在列的GenerateElement
和GenerateEditingElement
方法中创建的可视元素(控件):
protected abstract FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem);
protected abstract GenerateElement(DataGridCell cell, object dataItem);
如您所见,这些方法接受从IEnumerable
检索的非类型化object
。与所有其他绑定一样,使用反射解析实际属性值。这些列只是将绑定应用到生成的元素。
如果您想创建自定义列,您应该从 DataGridBoundColumn
或其任何子级继承,并按原样使用现有的 Binding
属性。
【讨论】:
感谢您的评论。但是,它并没有完全回答我的问题。即使我(正确地)从 DataGridBoundColumn 继承,我自己的属性的行为方式仍然与 Binding 属性不同(即自动绑定到可枚举中的当前项,即使有智能感知支持)。 Telerik 的 DataGrid 还实现了一个 DataMemberBinding 属性,该属性的行为类似于 Binding 属性,因此我必须缺少一些东西才能以相同的方式实现它。 @GeorgeB:如何表现相同?在 Visual Studio 中?你在用 Resharper 还是别的什么?以上是关于如何将自定义列的数据上下文设置为 ItemsSource 项目类型?的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式将自定义图像设置为 UIBarButtonItem
Swift:如何将自定义 UICollectionViewCell 设置为圆形?
Django 如何将自定义变量传递给上下文以在自定义管理模板中使用?
如何将自定义 ListAdapter 设置为 appwidget 中的列表视图?