Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
456 views
in Technique[技术] by (71.8m points)

c# - Change View with its ViewModel based on a ViewModel Property

As far as I know in WPF you can do something like this:

<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>

My question: Is there any way to choose the View based on a property in your ViewModel?

something like this:

<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>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Would a datatemplate selector do this?

tutorial here

This is how this would apply to your scenario:

First create a 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;
    }
}

I have extended the tutorial to include properties you can assign for when to return each template.

Declare the XAML resources

<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>

In this example we have declared our selector so that when our property has value 1, template1 is returned, otherwise we get template 2.

Add Control to XAML Finally, a little hack is needed - your VM property needs to be IEnumerable...

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

I hope this helps, please mark as answer if you found it useful


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...