All*_*nek 2 .net c# wpf xaml datatemplate
在回答之前:这个问题是关于WPF的ListView控制(带GridView).它不是关于WPF的DataGrid控件,ASP.NET DataGrid或ListView控件,或WinForm DataGridView或ListView控件.它们听起来非常相似并经常混淆,但错误控制类型的答案对我来说无益,更重要的是浪费你写答案的时间,我认为不应该浪费.
我有一个ListView控件GridView,有几列绑定到我的视图模型的属性.我可以GridViewColumn通过指定CellTemplate(内联或通过资源)轻松自定义单元格的视觉外观.
现在我的视图模型上有一个特定的属性; 它的类型是一个抽象基类,它的值可以是几种派生类型之一.每个派生类型DataTemplate在单元格中应该有不同的类型.幸运的是,GridViewColumn有一个CellTemplateSelector完全符合我的要求,但需要编写一些管道代码.但是看一下DataTemplateSelector它的页面说:
请注意,如果您有不同类型的对象,则可以在DataTemplate上设置DataType属性.如果这样做,则无需创建DataTemplateSelector.[...]有关更多信息,请参阅数据模板概述.
欢呼!无需编写管道代码.我的类型是不同的,因此这似乎是一个完美的结合.但是,即使在我定义了DataTemplate一个DataType匹配数据绑定列之一(使用GridViewColumn's 绑定)的特定派生类型之后DisplayMemberBinding,它也没有效果.
我只想DataTemplate根据我的某个列的运行时类型显示不同的GridView.是DataType靶向性DataTemplates根本不兼容GridView?有没有办法使用它们,还是我必须指定一个CellTemplateSelector?或许有指定多个方式DataTemplate在s GridViewColumn的CellTemplate,这样DataType属性将产生效果?
WPF允许您插入对象,例如ViewModels在逻辑树中,而a DataTemplate可以用于告诉WPF在绘制可视树时如何绘制指定的对象.
隐式DataTemplate是DataTemplate只有一个已DataType定义的(no x:Key),并且只要WPF尝试在VisualTree中呈现指定类型的对象,它就会自动使用.
所以,你可以使用
<Window.Resources>
<DataTemplate DataType="{x:Type local:ViewModelA}">
<local:ViewA />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelB}">
<local:ViewB />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelC}">
<local:ViewC />
</DataTemplate>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)
告诉WPF使用ViewA绘制ViewModelA,使用ViewB绘制ViewModelB,使用ViewC绘制ViewModelC.
如果你只想将它应用到你的GridView而不是整个Window,你可以指定<GridView.Resources>(或者<ListView.Resources>,我不记得哪一个)
应该注意的是,如果使用the绑定列DisplayMemberBinding,它将呈现为绑定到您的属性TextBox的Text值,这意味着它将呈现YourViewModel.ToString()而不是尝试使用您的VisualTree中的ViewModel DataTemplate.
为了避免这种情况,只需将CellTemplate要像一个ContentPresenter与Content绑定到你的财产ViewModel,它会使用您的暗示使您的视图模型DataTemplates
<GridViewColumn Header="Some Header">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding YourViewModelProperty}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Run Code Online (Sandbox Code Playgroud)