【问题标题】:Multiple input forms with same xaml file and different DataContexts具有相同 xaml 文件和不同 DataContexts 的多个输入表单
【发布时间】:2014-06-09 13:19:33
【问题描述】:

我正在使用 XAML 和 MVVM Light 开发 WinRT 应用程序。该应用程序旨在使用户在现场时更容易进行数据收集。我的应用程序有一个部分,用户需要在其中输入有关几个不同项目的大量信息。这些项目被定义为从GenericAsset 类继承的类。 GenericAsset 具有如下字段:

public class GenericAsset
{
    public string AssetId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}

子类看起来像这样:

public class SubAsset1 : GenericAsset
{
    public string RecordNumber { get; set; }
    public int SizeDiameter { get; set; }
    public string MaterialType { get; set; }
}

public class SubAsset2 : GenericAsset
{
    public string Type { get; set; }
    public int Size { get; set; }
    public string PlanRef { get; set; }
    public string InteriorMaterial { get; set; }
}

目前我有 15 个子资产(将来还会有更多),我正在寻找一种方法来创建一个数据输入视图/视图模型(如果可能的话),这样我就不必为每个资产。此外,如果我可以让通用视图/视图模型正常工作,我将如何加载自定义数据输入控件(特定于每个子资产的输入),同时保持正确的双向数据绑定到适当的子资产?

【问题讨论】:

  • 好吧,如果您不想为每个实体创建单独的视图或 DataTamplates,那么我想您必须以编程方式创建视图,并根据字段类型添加控件。
  • 就我个人而言,我会从两部分组成我的观点:一部分涵盖通用属性,另一部分特定于子资产类型。通过这种方式,我可以在输入数据时完全控制用户体验,并且可以(例如)决定 SubAsset2InteriorMaterial 属性的 UI 应该使用 DropDown 输入,而 PlanRef 需要特定的 RegEx来验证它。仅仅因为他们都是string 并不意味着他们应该只使用TextBox 来输入数据。
  • 目前我确实将视图分为两部分。我有一个通用资产信息部分和一个特定资产信息部分。我正在尝试找出拥有一个包含所有通用字段的视图的最佳方法,然后动态加载适当的特定字段,例如来自外部 XAML 文件或其他内容。

标签: c# xaml windows-runtime winrt-xaml mvvm-light


【解决方案1】:

您要查找的是DataTemplateSelector。为每个SubAsset 创建一个不同的DataTemplate。然后,通过ContentControl(或ListView,如果有多个)显示Asset。它们都有一个用于DataTemplateSelector 的插槽(分别为ContentTemplateSelectorItemTemplateSelector)。如果它们之间有相似的部分,您实际上可以通过使用指向目标DataTemplate(您希望组合的)的内部ContentControl 来组合一个DataTemplate

为了从不同的ResourceDictionaries 添加您的DataTemplates,当您创建DataTemplateSelector 时,请为您希望拥有的每个DataTemplate 创建一个属性。

您的选择器可能如下所示:

public class AssetDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate SubAsset1DataTemplate { get; set; }
    public DataTemplate SubAsset2DataTemplate { get; set; }
    ...

    // Data Template Selection Code
    ...
}

然后在 ResourceDictionary(例如 Generic.xaml)中,当您声明您的 AssetDataTemplateSelector 时,只需将所有其他 DataTemplates 引用为 StaticResources。

<!-- This assumes that AssetDataTemplateSelector has been declared in a namespace 
     defined in the root of the ResourceDictionary as 'converters'. -->
<!-- It also assumes that you have created DataTemplates with the names 
     SubAssetXDataTemplate either in the same or other ResourceDictionaries 
     which are accessible from this one. -->
<converters:AssetDataTemplateSelector x:Key="AssetDataTemplateSelector"
                                      SubAsset1DataTemplate="{StaticResource SubAsset1DataTemplate}"
                                      SubAsset2DataTemplate="{StaticResource SubAsset2DataTemplate}"
                                      ...
                                      />

【讨论】:

  • 谢谢!我会尝试一下。另外,如果我将所有DataTemplates 都放在单独的ResourceDictionary 文件中,我将如何使用ContentTemplateSelector
猜你喜欢
  • 2014-11-28
  • 1970-01-01
  • 2021-03-14
  • 2016-07-09
  • 2016-09-28
  • 1970-01-01
  • 2013-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多