干式子类化WPF窗口
我有几个WPF窗口,除了DataGrid上的列(DataContext将是不同对象的可观察集合)、一些标签中的文本和一个按钮单击处理程序之外,它们非常相似 对于每个窗口,数据网格的干式子类化WPF窗口,wpf,dry,subclassing,Wpf,Dry,Subclassing,我有几个WPF窗口,除了DataGrid上的列(DataContext将是不同对象的可观察集合)、一些标签中的文本和一个按钮单击处理程序之外,它们非常相似 对于每个窗口,数据网格的部分是不同的。它使用AutoGenerateColumns=“False”并为不同的对象显示不同的列 我想知道是否有可能对一个基本WPF窗口进行子类化,这样我就可以在XAML上为每个子类编写部分,而不是用代码编写它 或者还有什么其他技术可以在仍然使用XAML的情况下遵守WPF上的DRY原则呢?我会使用一个窗口和不同的数
部分是不同的。它使用AutoGenerateColumns=“False”
并为不同的对象显示不同的列
我想知道是否有可能对一个基本WPF窗口进行子类化,这样我就可以在XAML上为每个子类编写
部分,而不是用代码编写它
或者还有什么其他技术可以在仍然使用XAML的情况下遵守WPF上的DRY原则呢?我会使用一个窗口和不同的数据模板来实现这一点。但是,如果要使用继承,则可以使用基本窗口引用的键覆盖Window.Resources中的
DataTemplate
。DataTemplate
将具有整个数据网格的Xaml
如何从数据源填充DataGrid列 是的,您在这里遇到了一个限制。
列
属性不可绑定;事实上,它甚至不可设置,您只能从集合中添加和删除。这个问题有一个解决办法:
因此,从理论上讲,您可以将列添加到
,然后像上面的问题一样对附加属性进行数据绑定,并编写一个值转换器,根据数据源值构建列集合,从应用程序.Current.Resources
。但这似乎比它需要的更复杂
我认为您可以使用样式触发器,用不同的数据网格替换一些内容
:
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="Content">
<Setter.Value>
<DataGrid Style="{StaticResource CommonStyle}">
<DataGrid.Columns>
... default columns go here ...
</DataGrid.Columns>
</DataGrid>
<Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding SomeCondition}" Value="True">
<Setter Property="Content">
<DataGrid Style="{StaticResource CommonStyle}">
<DataGrid.Columns>
... alternate columns ...
</DataGrid.Columns>
</DataGrid>
</Setter>
</DataTrigger>
... additional triggers as needed ...
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
... 默认列位于此处。。。
... 交替列。。。
... 根据需要添加其他触发器。。。
这可能是一个更大的通用视图模板的一部分——不需要创建单独的视图类。您读过MVVM设计模式吗?听起来您可以使用具有不同视图模型的单个视图,甚至可能使用单个视图模型(唯一的区别是每个窗口的数据不同)。是的,我会为ObservableCollection中的每种类型的对象使用不同的视图模型,子类化或使用模板,这没有问题。问题在于避免视图中的重复。为什么不能对每个窗口使用相同的视图?如果唯一的区别是文本之类的东西,则将这些文本字符串设置为视图模型的可绑定属性。对按钮连接到的
ICommand
执行相同操作(不要使用单击事件处理程序)。从基础数据源填充网格列。如果使用AutoGenerateColumns=“False”
,如何从数据源填充DataGrid列?我不想显示数据中的所有字段,我需要添加一个带有按钮的额外列。您可以使用ITypedList
仅显示所需列的属性描述符。您可以包装结果行。您可以使用[可浏览(false)]
注释未显示的属性。您可以调用视图模型来检索列名列表。有很多解决方案。我认为通常建议不要在setter值中使用UI元素,但通过用ContentTemplate
setter替换Content
setter,可以实现几乎相同的效果。您只需要将DataGrid
包装在DataTemplate
@MikeStrobel中。如果我们使用内容模板,我们还需要添加content=“{Binding}”
。我宁愿用ContentControl
交换Control
并设置ControlTemplate
@nmclean啊,是的,如果你想继续绑定上下文,那你是对的。