Price Jones
Price Jones

Reputation: 2008

Switch out UserControl based on property

How do I switch UserControls based on a property setting in my ViewModel?

If Vm.View = "A"

<Window>
<local:UserControlA/>
</Window>

If Vm.View = "B"

<Window>
<local:UserControlB/>
</Window>

Vm.View is an enum that someday may allow for C, D, and so on. Both UserControls are bound to the same Vm, but they present the data radically different based on the user's input. So a DataTemplate based on type doesn't really work here.

Thoughts?

Upvotes: 2

Views: 1353

Answers (2)

blins
blins

Reputation: 2535

You might leverage DataTemplate's DataType property and let the binding engine take care of the rest...

XAML

<Window.Resources>
    <DataTemplate DataType="localEnums:ProduceType.Apples">
        <local:ApplesView />
    </DataTemplate>
    <DataTemplate DataType="localEnums:ProduceType.Oranges">
        <local:OrangesView />
    </DataTemplate>
</Window.Resources>
<StackPanel>
    <ContentPresenter Content="{Binding ProduceType}" />
    <Button Content="Change Produce" Click="Button_Click"/>
</StackPanel>

View Model

public class ProduceViewModel : ViewModel
{
    public ProduceViewModel()
    {
        this.ProduceType = ProduceType.Apples;
    }

    private ProduceType _produceType;

    public ProduceType ProduceType
    {
        get
        {
            return _produceType;
        }
        set
        {
            if (_produceType != value)
            {
                _produceType = value;
                RaisePropertyChanged();
            }
        }
    }
}

Button Click Handler (Violates pure MVVM but just to demonstrate the DataTemplate switching)

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        (this.DataContext as ProduceViewModel).ProduceType = ProduceType.Oranges;
    }

Upvotes: 2

Rohit Vats
Rohit Vats

Reputation: 81253

Add ContentControl inside Window and based on View value you can set it's ContentTemplate using DataTriggers.

<ContentControl Content="{Binding}">
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <local:UserControlA/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <DataTrigger Binding="{Binding View}" Value="B">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <local:UserControlB/>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

Upvotes: 2

Related Questions