MVVM 中的数据模板是否已过时?

2023-12-13

我创建了以下模型(简化了代码以说明情况):

public abstract class Account
{
    public string Name { get; set; }
}

public class Person : Account
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Company : Account
{
    public string Owner { get; set; }
}

接下来我创建了一个视图模型:

public class ViewModel
{
    public Account Model { ... }
    public string Name { ... }
    public string FirstName { ... }
    public string LastName { ... }
    public string Owner { ... }   
    ...
}

最后,观点:

<UserControl>
  <UserControl.Resources>

    <!-- Person data template -->
    <DataTemplate x:Key="personTemplate" DataType="{x:Type model:Person}">
      <Grid DataContext="{Binding ElementName=rootLayout, Path=DataContext}">
        <TextBlock Text="{Binding Path=Name}" />
        <TextBlock Text="{Binding Path=FirstName}" />
        <TextBlock Text="{Binding Path=LastName}" />
      </Grid>
    </DataTemplate>

    <!-- Company data template -->
    <DataTemplate x:Key="companyTemplate" DataType="{x:Type model:Company}">
      <Grid DataContext="{Binding ElementName=rootLayout, Path=DataContext}">
        <TextBlock Text="{Binding Path=Name}" />
        <TextBlock Text="{Binding Path=Owner}" />
      </Grid>
    </DataTemplate>

    <!-- Data template selector for different account types -->
    <local:AccountTemplateSelector x:Key="templateSelector" 
        PersonTemplate="{StaticResource personTemplate}" 
        CompanyTemplate="{StaticResource companyTemplate}" />

  </UserControl.Resources>

  <StackPanel Name="rootLayout" DataContext="{Binding Path=viewModel}">
    <ContentControl Content="{Binding Path=Model}" 
        ContentTemplateSelector="{StaticResource templateSelector}"/>
    <Button Content="Save" />
    <Button Content="Close" />
  </StackPanel>

</UserControl>

因此,当加载的模型类型为Person the personTemplate显示;反之亦然,当模型为Company the companyTemplate显示。

我的问题是:

  1. 这种方法有意义吗?删除它会更明智吗?Model财产在ViewModel类并引入一个枚举或只是一个简单的bool这会告诉人们如果true,或公司,如果“假”?
  2. 在定义数据模板时,我指定了DataTypes to Person and Company类型(对我来说这样做是很自然的)。我是否需要它,因为在最 下一行我将设置一个新的数据上下文作为来自UserControl?
  3. 应该DataType数据模板可以是不同的视图模型,比如PersonViewModel and CompanyViewModel?创建它们有意义吗?
  4. 我怎样才能,我到底能不能让数据模板继承数据上下文ContentControl自动地?

我知道这一切最终都是个人选择的问题,但由于我正在学习 MVVM(我正在使用 MVVM Light),我想知道哪种方法是最值得推荐的?我仍然不完全理解何时应将模型中的类用作数据模板的数据类型以及何时应将视图模型用于此目的。表示模型的程序集是否应该在视图程序集中引用(假设视图、模型和视图模型都驻留在单独的程序集中)?

感谢您的所有澄清!

UPDATE:

此更新应该解释模型类的问题DataType当模态类的属性不直接绑定到视图中的一个控件时,数据模板中会出现 s 。

有一个枚举和一个新属性Person,所以现在看起来像这样:

public class Person : Account
{
    public enum GenderType { Female, Male, NotSpecified }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public GenderType Gender {get; set; }
}

在视图中,人员的数据模板当然也发生了变化:

<!-- Person data template -->
<DataTemplate x:Key="personTemplate" DataType="{x:Type model:Person}">
  <Grid DataContext="{Binding ElementName=rootLayout, Path=DataContext}">
    <TextBlock Text="{Binding Path=Name}" />
    <TextBlock Text="{Binding Path=FirstName}" />
    <TextBlock Text="{Binding Path=LastName}" />
    <RadioButton Name="Female" />
    <RadioButton Name="Male" />
    <RadioButton Name="NotSpecified" />
  </Grid>
</DataTemplate>

If the Content of the ContentControl被设定为Model的财产ViewModel,我将如何解决性别/单选按钮的情况;因为,现在它们以一个控件/一个属性的方式不匹配?


我会把它改成这样:

<UserControl>
  <UserControl.Resources>
    <!-- Person data template -->
    <DataTemplate DataType="{x:Type model:Person}">
      <Grid>
        <TextBlock Text="{Binding Path=Name}" />
        <TextBlock Text="{Binding Path=FirstName}" />
        <TextBlock Text="{Binding Path=LastName}" />
        <RadioButton Name="Female"       IsChecked="{Binding Gender , Converter={StaticResource enumBooleanConverter}, ConverterParameter=Female}" />
        <RadioButton Name="Male"         IsChecked="{Binding Gender , Converter={StaticResource enumBooleanConverter}, ConverterParameter=Male}" />
        <RadioButton Name="NotSpecified" IsChecked="{Binding Gender , Converter={StaticResource enumBooleanConverter}, ConverterParameter=NotSpecified }" />
      </Grid>
    </DataTemplate>

    <!-- Company data template -->
    <DataTemplate DataType="{x:Type model:Company}">
      <Grid>
        <TextBlock Text="{Binding Path=Name}" />
        <TextBlock Text="{Binding Path=Owner}" />
      </Grid>
    </DataTemplate>
  </UserControl.Resources>

  <StackPanel DataContext="{Binding viewModel}">
    <ContentControl Content="{Binding Model}" />
    <Button Content="Save" />
    <Button Content="Save" />
    <Button Content="Close" />
  </StackPanel>

</UserControl>

像这样,您可以为类定义隐式样式,并且不必使用模板选择器。另外,你不需要所有的字符串属性ViewModel class:

public class ViewModel
{
    public Account Model { ... } 
    ...
}

免责声明,单选按钮中的绑定使用来自的转换器here.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MVVM 中的数据模板是否已过时? 的相关文章

  • WPF 日历控件按住鼠标

    所以我放弃了标准的 WPFCalendarVS2010 中全新 WPF 应用程序中的 MainWindow xaml 控件 如果我单击日历中的某一天 然后尝试单击应用程序的 关闭 按钮 则我必须在关闭按钮上单击两次才能接受单击 它的表现就好
  • RichTextbox SelectionStart 返回错误的索引

    我需要向用户显示光标上文本的选择开始和长度 就像在 notepad exe 中一样 选择长度没有问题 因为 Richtextbox 支持带有开始和结束的选择属性 http msdn microsoft com en us library s
  • 输入按键的淘汰赛事件绑定会导致奇怪的行为

    长话短说 我希望用户能够在输入元素上按 Enter 键 并调用我的视图模型中的某些方法 这是我的 html 输入
  • 如何使用 WPF 用户控件关闭父窗口

    假设我有两个 WPF 窗口 window One 和 window Two window One 有一个按钮 单击此按钮将打开 window Two window Two contains a User Control 该用户控件有一个用于
  • 使用backgroundworker手动停止调试

    我正在编写一个 WPF C 项目 使用BackgroundWorker 带有进度条的弹出窗口 我开始调试 F5 键 来检查我的程序 之后BackgroundWorker完成并关闭弹出窗口 关闭MainWindow不会自动停止调试过程 我必须
  • 更改窗口的内容 (WPF)

    我创建了一个简单的 WPF 应用程序 它有两个 Windows 用户在第一个窗口中填写一些信息 然后单击 确定 这会将他们带到第二个窗口 这工作正常 但我试图将两个窗口合并到一个窗口中 这样只是内容发生了变化 我设法找到了这个更改窗口内容时
  • WPF 画布缩放/变换以适合

    我重新发布这个问题 因为上次我没有得到太多答复 希望重新措辞可能有所帮助 本质上 我想做的是创建一个数据绑定画布 它将自动缩放其内容以 填充 可用空间 有点像缩放以适应操作 不幸的是 我的 WPF 技能还不是很强 我正在努力弄清楚如何完成最
  • 如何在 XAML/WPF 中存储和检索多个形状?

    使用 XAML WPF 做一些简单的事情似乎遇到了很多问题 我已经使用矩形和椭圆形等形状创建了一些基于 XAML 的图像来创建我需要应用程序的其他部分使用的图标 但我不能似乎找到了如何做到这一点 我似乎能够在资源字典中存储画布 但无法在任何
  • 从代码中,如何创建对存储在附加属性中的对象的属性的绑定?

    我们有一个继承的附加属性来存储一个对象 在可视化树的更下方 我们希望从代码绑定到该对象的属性 通常我们像这样构建绑定的路径部分 var someBinding new Binding Path new PropertyPath Attach
  • WindowsFormsHost ZOrder

    看起来 WindowsFormsHost 控件被设置为显示在顶部 有没有办法更改其 z 顺序 以允许同一窗口上的其他 WPF 控件在 WindowsFormsHost 控件之上可见 不幸的是 不能 由于 winformshost 合成到 W
  • DataContractSerializer 事件/委托字段问题

    在我的 WPF 应用程序中 我正在使用DataContractSerializer序列化对象 我发现它无法序列化具有事件或委托声明的类型 考虑以下失败的代码 Serializable public abstract class BaseCl
  • System.Windows.Controls.WebBrowser、System.Windows.Threading.Dispatcher 和 Windows 服务

    我正在尝试将一些 html 内容渲染为 Windows 服务中的位图 我正在使用 System Windows Controls WebBrowser 来执行渲染 基本渲染设置作为一个独立进程运行 并带有托管控件的 WPF 窗口 但作为服务
  • 命令绑定到 ContextMenu(在 ListBox 中的 ListBoxItem 上)不起作用[重复]

    这个问题在这里已经有答案了 在 WPF 中 借助 MVVM 光 有一个Class 由一些学生组成 以及Class持有一些Students 右键单击一个学生的名字 然后会显示一个MessageBox 这样就可以了 类详细信息视图 xaml
  • WPF - 全局添加xaml命名空间声明

    我有一个相当大的 WPF 应用程序 其中包含大量 XAML 文件 每个 XAML 文件都有 5 到 10 个 clr 到 xml 命名空间映射xmlns abc clr namespace Abcdef 它看起来很糟糕 并且在每个文件中写入
  • 为什么有时Task明显慢于Thread?

    我正在使用 MVVM 模式制作 WPF 应用程序 我发现有时任务明显慢于线程 例如 在测试 ViewModel 中 public void DoSomething Stopwatch stopwatch Stopwatch StartNew
  • MVVM 在 ASP.NET MVC 4 Web 应用程序中扮演什么角色?

    当我正在阅读 ASP NET MVC 4 这本书时 我对 MVVM 感到好奇 我开始谷歌搜索 找不到任何关于使用 MVVM 开发 Web 应用程序的书籍 所以我一定在这里遗漏了一些信息 据我了解 MVVM是通过knockout js和其他框
  • 如何在WPF中裁剪图像并保存到ImageSource中?

    我是 WPF 的新学员 我有一个问题 我有一个图像 宽度 360 高度 360 在这里 我想裁剪该图像 如下所示 0 0 到 120 120 保存到第一个 ImageSource 对象 120 0 到 240 120 保存到第二个 Imag
  • 带有 Prism 区域适配器的 AvalonDock

    我看到了一些关于 SO 的问题 但似乎没有一个适合我 我希望能够使用伟大的使用 Prism 4 但是 所有示例区域适配器均适用于 Avalondock 1 x 系列 我无法使其工作 有人有关于如何为 AvalonDock 的 LayoutD
  • 有没有办法对 RichTextBox 的撤消历史进行分组或暂时禁用它?

    我目前正在研究 WPF 中 RichTextBox 内的表格 在 WPF 中 表格没有行和列 只有行 每行都有一定数量的单元格 当用户按下 添加列 按钮时 我的程序会向每一行添加一个新单元格 使用此方法的问题是 在用户添加一列后 如果他们按
  • 如何使用 MVVM 更改数据网格或列表视图中的内容

    我有一个 MainWindowViewModel DataContext 它公开不同的 ObservableCollections 带有 INotifyProperty 的 poco 对象的视图模型 从组合框中选择一个值后 我想单击一个加载

随机推荐