【问题标题】:Selecting DataTemplate from Window Resource in ViewModel with MVVM使用 MVVM 从 ViewModel 中的窗口资源中选择 DataTemplate
【发布时间】:2018-10-02 01:59:23
【问题描述】:

我有一个视图,其中窗口的一小部分显示用户单击的项目的详细信息。这些细节的格式发生了变化,所以我最初的实现对不同种类的项目有一个隐藏/显示逻辑:

<Grid Name="Details1" Visibility="Collapsed">
    <TextBox Name="Details_Field1" />
</Grid>
<Grid Name="Details2" Visibility="Visible">
    <TextBox Name="Details_Field2" />
    <TextBox Name="Details_Field3" />
</Grid>
<Grid Name="Details3" Visibility="Collapsed">
    <TextBox Name="Details_Field4" />
    <TextBox Name="Details_Field5" />
    <DataGrid Name="Details_DataGrid1 />
</Grid>

现在,我想让这个“不那么糟糕”。我的策略是让这些网格中的每一个都成为自己的 DataTemplate,并像这样管理状态:

查看:

<Window.Resource>
    <DataTemplate x:Key="Details_Template1>
        <Grid Name="Details1">
            <TextBox Name="Details_Field1" />
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="Details_Template2>
        <Grid Name="Details2">
            <TextBox Name="Details_Field2" />
            <TextBox Name="Details_Field3" />
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="Details_Template3>
        <Grid Name="Details3">
            <TextBox Name="Details_Field4" />
            <TextBox Name="Details_Field5" />
            <DataGrid Name="Details_DataGrid1 />
        </Grid>
    </DataTemplate>
</Window.Resources>

....

<Grid Name="DetailsGoHere">
    <ContentControl ContentTemplate="{Binding DetailsDisplay}" />
</Grid>

视图模型:

    private DataTemplate _detailsDisplay;
    public DataTemplate DetailsDisplay
    {
        get => _detailsDisplay;
        private set => RaisePropertyChangedEvent(ref _detailsDisplay, value);
    }

....

private void Item_OnClick()
{
    // Pseudocode!  How do I reference Details_Template1 as a resource?
    DetailsDisplay = MyView.Details_Template1;
}

正如评论所暗示的,我不确定如何从我的 ViewModel 引用我的 Window.Resource 块中的 DataTemplates,所以我的问题是双重的:

1:这是解决这类问题的好方法吗?

2:如果是这样,我如何从我的 ViewModel 中的 Window.Resource 块中引用一个项目?

【问题讨论】:

    标签: c# wpf mvvm datatemplate


    【解决方案1】:

    DataTemplateSelector用于在WPF中切换DataTemplate。

    具体实现请参考此链接http://www.wpftutorial.net/datatemplates.html

    PropertyDataTemplateSelector-

    public class PropertyDataTemplateSelector : DataTemplateSelector
    {
    public DataTemplate DefaultnDataTemplate { get; set; }
    public DataTemplate BooleanDataTemplate { get; set; }
    public DataTemplate EnumDataTemplate { get; set; }
    
    public override DataTemplate SelectTemplate(object item, 
               DependencyObject container)
    {
        DependencyPropertyInfo dpi = item as DependencyPropertyInfo;
        if (dpi.PropertyType == typeof(bool))
        {
            return BooleanDataTemplate;
        }
        if (dpi.PropertyType.IsEnum)
        {
            return EnumDataTemplate;
        }
    
        return DefaultnDataTemplate;
       }
    }
    

    查看 -

    <Window x:Class="DataTemplates.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:l="clr-namespace:DataTemplates"
    xmlns:sys="clr-namespace:System;assembly=mscorlib">
    
    <Window.Resources>
    
        <!-- Default DataTemplate -->
        <DataTemplate x:Key="DefaultDataTemplate">
           ...
        </DataTemplate>
    
        <!-- DataTemplate for Booleans -->
        <DataTemplate x:Key="BooleanDataTemplate">
           ...
        </DataTemplate>
    
        <!-- DataTemplate for Enums -->
        <DataTemplate x:Key="EnumDataTemplate">
            ...
        </DataTemplate>
    
        <!-- DataTemplate Selector -->
        <l:PropertyDataTemplateSelector x:Key="templateSelector"
              DefaultnDataTemplate="{StaticResource DefaultDataTemplate}"
              BooleanDataTemplate="{StaticResource BooleanDataTemplate}" 
              EnumDataTemplate="{StaticResource EnumDataTemplate}"/>
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding}" Grid.IsSharedSizeScope="True" 
                 HorizontalContentAlignment="Stretch" 
                 ItemTemplateSelector="{StaticResource templateSelector}"/>
    </Grid>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      相关资源
      最近更新 更多