【问题标题】:Change View with its ViewModel based on a ViewModel Property基于 ViewModel 属性使用其 ViewModel 更改 View
【发布时间】:2014-07-23 17:08:46
【问题描述】:

据我所知,您可以在 WPF 中执行以下操作:

<Window.Resources>
    <DataTemplate DataType="{x:Type ViewModels:IronStage1ViewModel}">
        <Views:IronStage1View/>
    </DataTemplate>

    <DataTemplate DataType="{x:Type ViewModels:IronStage2ViewModel}">
        <Views:IronStage2View/>
    </DataTemplate>
    <Views:TestStageToTabIndexConverter x:Key="TestStageToTabIndexConverter" />
</Window.Resources>

我的问题: 有什么方法可以根据 ViewModel 中的属性选择 View?

类似这样的:

<Window.Resources> //If property Selector==1
    <DataTemplate DataType="{x:Type ViewModels:IronStage1ViewModel}"> 
        <Views:IronStage1View/>
    </DataTemplate>

                   // If property Selector==2
    <DataTemplate DataType="{x:Type ViewModels:IronStage1ViewModel}">
        <Views:IronStage2View/>
    </DataTemplate>
</Window.Resources>

【问题讨论】:

  • 想到数据触发器,这也可以通过转换器完成。你有什么特别好奇的实现吗?
  • 对不起,我不明白你的意思是什么,再见具体的实现。但只是说我使用 Ninject 作为我的 DI 容器,并且我尽量遵守所有设计模式。

标签: c# .net wpf


【解决方案1】:

数据模板选择器会这样做吗?

tutorial here

这将如何应用于您的场景:

首先创建一个DataTemplateSelector:

public class IronStageTemplateSelector : DataTemplateSelector
{
    public DataTemplate IronStage1Template { get; set; }
    public DataTemplate IronStage2Template { get; set; }

    public object IronStage1Selector { get; set; }
    public object IronStage2Selector { get; set; }

    public override DataTemplate SelectTemplate(object selector,
      DependencyObject container)
    {
        if(selector == this.IronStage1Selector)
        {
            return IronStage1Template;
        }

        return IronStage2Template;
    }
}

我已经扩展了本教程以包含您可以指定何时返回每个模板的属性。

声明 XAML 资源

<UserControl.Resources>
    <DataTemplate x:Key="iron1Template">
        <TextBlock/>
    </DataTemplate>

    <DataTemplate x:Key="iron2Template">
        <Label />
    </DataTemplate>

    <System:Double x:Key="Selector1">1</System:Double>
    <System:Double x:Key="Selector2">2</System:Double>

    <local:IronStageTemplateSelector x:Key="IronStageTemplateSelector" 
                                     IronStage1Selector="{StaticResource Selector1}"
                                     IronStage2Selector="{StaticResource Selector2}"
                                     IronStage1Template="{StaticResource iron1Template}"
                                     IronStage2Template="{StaticResource iron2Template}"/>
</UserControl.Resources>

在这个例子中,我们声明了我们的选择器,这样当我们的属性值为 1 时,返回模板 1,否则我们得到模板 2。

向 XAML 添加控件 最后,需要一点技巧 - 你的 VM 属性需要是 IEnumerable...

<ItemsControl ItemsSource="{Binding toProperty}" 
     ItemTemplateSelector="{StaticResource IronStageTemplateSelector}">
</ItemsControl>

希望对你有帮助,如果觉得有用请标记为答案

【讨论】:

  • 这应该是答案,但您需要提供一些细节,以防 url 变得无效。
  • 当然 - 已通过手机发布答案,明天将从桌面更新。
  • 谢谢@kidshaw。有用。想看 DataTemplateSelector 视频教程的朋友,也可以看看这个 (youtube.com/watch?v=CAbshQcI1BA)
  • 一半的答案是首先知道要谷歌什么!很高兴我能帮上忙。
【解决方案2】:

在编译时视图模型属性是已知类型吗?如果是这样,您可以直接将控件添加到主(父)视图并将数据上下文绑定到视图模型属性。

类似的东西..

   <Address:AddressControl Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="6" DataContext="       {Binding PresentAddress}"/>

如果您有不同的情况,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-19
    • 2014-12-10
    • 1970-01-01
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多