wpf - 我应该使用 DataTemplates 还是 UserControl 来显示扩展类的不同控件?

标签 wpf user-controls datatemplate extends

我有一个 User 类和一个扩展 User 的 Author 类。我有一个 ObservableCollection 显示在列表框中。为此,我有一个 DataTemplate 来显示每个项目,另一个 DataTemplate 来显示每个选定的项目。我还有一列 TextBoxes,它们绑定(bind)到 ListBox.SelectedItem 属性的属性。到目前为止,一切顺利。

目前,如果所选用户是作者并且一切正常,我会在列和数据模板中显示额外的控件,但我在作弊。我在 User 类中添加了 IsAuthor bool 属性,以便我可以绑定(bind)到它并确定用户是否是作者。我知道这是错误的,但我无法找到任何其他方法来做到这一点,所以我的第一个问题是如何以与基类不同的方式显示扩展类?我为作者类型尝试了不同的 DataTemplate,但它从未起作用...也许是因为该集合的类型为 User?

第二个问题是我是否应该将所有许多 TextBox 控件放在 UserControl 的列中并更改与 Author 相关的控件的可见性,或者以某种方式将它们放入 DataTemplate 中并为每种类型创建一个?我当前使用第一种方法,问题是当当前所选项目不是作者时,绑定(bind)到 Author 属性的每个控件都会抛出错误(我可以在 Visual Studio 的输出窗口中看到它们)。

最佳答案

我有一个类似的设置,它使用数据模板,并且它与继承的类一起工作得很好。我就是这样做的。

<ListBox Name="UserList" ItemsSource="{Binding Path=Users}"
         ItemTemplate="{StaticResource ShowUserName}"
         SelectedItem="{Binding Path=SelectedUser, Mode=TwoWay}">
</ListBox>
<ContentControl Content="{Binding ElementName=UserList, Path=SelectedItem}"/>

在 Window.Resources 部分中,我有以下数据模板:

<DataTemplate x:Key="ShowTime" DataType="TestApp.User">
    <TextBlock Text="{Binding Path=Name}" HorizontalAlignment="Center"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:User}">
   <StackPanel Margin="10">
     <TextBlock Text="{Binding Path=Name}"/>
     <TextBlock Text="{Binding Path=Age}"/>
   </StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Author}">
   <StackPanel Margin="10">
     <TextBlock Text="{Binding Path=Name}"/>
     <TextBlock Text="{Binding Path=Age}"/>
     <TextBlock Text="{Binding Path=FirstTitle}"/>
   </StackPanel>
</DataTemplate>

第一个模板将显示在列表本身中。我们在列表框的 ItemTemplate 属性中通过键引用它。内容控件在确定为所选项目显示什么内容时使用其他两个数据模板。当选择的项目只是一个User时,将显示User DataTemplate,如果选择一个作者,将显示作者DataTemplate。

x:Type local:Author 指的是类类型。 local 应在您的 namespace 声明中声明。

xmlns:local="clr-namespace:TestApp"

请记住,这是我的命名空间,您必须指定您正在使用的命名空间。当然,数据模板只是基本示例,想必您会想要做一些更适合您的应用程序的事情。

但是,必须为两个类定义几乎完全相同的两个单独的数据模板可能会令人恼火。虽然你当然可以。我在自己的应用程序中执行此操作(不在本例中),因为我想要为每种类型显示的内容有很大不同。

因此,可能有用的是为所有用户属性创建一个通用的数据模板,并简单地为作者扩展此数据模板。如果您想这样做,可以这样设置模板:

<DataTemplate x:Key="UserTemplate">
  <!-- show all the properties of the user class here -->
</DataTemplate>
<DataTemplate DataType="{x:Type local:User}">
  <ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource UserTemplate}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Author}">
  <StackPanel>
    <ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource UserTemplate}"/>
    <!-- show all the additional Author properties here -->
  </StackPanel>
</DataTemplate>

正如您所看到的,用户和作者的数据模板都开始使用名为“UserTemplate”的数据模板。但在作者数据模板中,我们将添加作者特定的属性。

希望对您有所帮助。

关于wpf - 我应该使用 DataTemplates 还是 UserControl 来显示扩展类的不同控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4433974/

相关文章:

c# - 设置宽度属性时代码隐藏中的 WPF DataTemplate 崩溃

c# - 获取部分属性(property)的逻辑。好的做法?

wpf - 为什么这个 WPF ComboBox 没有显示选定的值?

wpf - 如何根据属性值禁用数据绑定(bind)的 ListBox 项?

c# - 如何从 WPF MVVM 中的用户控件创建 PDF

c# - 两个单独的 UserControls 似乎是同一个实例

c# - 如何使用自定义 DefaultBackColor 制作 UserControl?

c# - 返回 PDF 页面的 SHA256 哈希值

c# - WPF Prism Bound 字段值在命令触发之前不可用

c# - 根据多个条件过滤 CollectionView