干式子类化WPF窗口

干式子类化WPF窗口,wpf,dry,subclassing,Wpf,Dry,Subclassing,我有几个WPF窗口,除了DataGrid上的列(DataContext将是不同对象的可观察集合)、一些标签中的文本和一个按钮单击处理程序之外,它们非常相似 对于每个窗口,数据网格的部分是不同的。它使用AutoGenerateColumns=“False”并为不同的对象显示不同的列 我想知道是否有可能对一个基本WPF窗口进行子类化,这样我就可以在XAML上为每个子类编写部分,而不是用代码编写它 或者还有什么其他技术可以在仍然使用XAML的情况下遵守WPF上的DRY原则呢?我会使用一个窗口和不同的数

我有几个WPF窗口,除了DataGrid上的列(DataContext将是不同对象的可观察集合)、一些标签中的文本和一个按钮单击处理程序之外,它们非常相似

对于每个窗口,数据网格的
部分是不同的。它使用
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啊,是的,如果你想继续绑定上下文,那你是对的。