Change view for ViewModel

I am trying to implement an MVVM design pattern for a WPT application for mt. To connect the view to view modes, I use ResourceDictionary(used in Application.Resources), which looks like

<DataTemplate DataType={x:Type viewmodel:SampleViewModel}>
    <view:SampleView1 />
</DataTemplate>

Presentation models are then simply placed on content presenters to display them.

Now, when the user clicks the button, I would like to display SampleViewModelusing a different view. How to change the data template used for SampleViewModel?

+5
source share
3 answers

. , SampleViewModel. Title ViewType :

public enum ItemViewType { View1, View2 };

public class SampleViewModel 
{
    public string Title { get; set; }
    public ItemViewType ViewType { get; set; }
}

DataTemplateSelector ViewType:

class ItemViewTemplateSelector : DataTemplateSelector
{
    public DataTemplate View1Template { get; set; }
    public DataTemplate View2Template { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var vm = item as SampleViewModel;
        if (vm == null)
            return null;

        switch (vm.ViewType)
        {
            case ItemViewType.View1:
                return View1Template;
            case ItemViewType.View2:
                return View2Template;
        }

        return null;
    }
}

Xaml:

<Window.Resources>
    <DataTemplate x:Key="view1Template">
        <TextBlock Text="{Binding Title}" Foreground="Red"/>
    </DataTemplate>
    <DataTemplate x:Key="view2Template">
        <TextBox Text="{Binding Title}" />
    </DataTemplate>
    <local:ItemViewTemplateSelector x:Key="viewTemplateSelector"
                                    View1Template="{StaticResource view1Template}"
                                    View2Template="{StaticResource view2Template}"/>
</Window.Resources>

<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>

<StackPanel>
    <Button Content="ChangeView" HorizontalAlignment="Center" Command="{Binding SwitchViewCommand}"/>
    <ContentControl  Content="{Binding ItemViewModel}" ContentTemplateSelector="{StaticResource viewTemplateSelector}"/>
</StackPanel>

MainViewModel, :

public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        this.ItemViewModel = new SampleViewModel { Title = "Some title", ViewType = ItemViewType.View1 };

        this.SwitchViewCommand = new RelayCommand(() =>
        {
            this.ItemViewModel.ViewType = this.ItemViewModel.ViewType == ItemViewType.View1
                                            ? ItemViewType.View2
                                            : ItemViewType.View1;
            //The magic senquence of actions which forces a contentcontrol to change the content template
            var copy = this.ItemViewModel;
            this.ItemViewModel = null;
            this.ItemViewModel = copy;
        });
    }

    public RelayCommand SwitchViewCommand { get; set; }

    private SampleViewModel itemViewModel;

    public SampleViewModel ItemViewModel
    {
        get { return itemViewModel; }
        set
        {
            itemViewModel = value;
            RaisePropertyChanged("ItemViewModel");
        }
    }
}

SwitchViewCommand , mvvmlight.

viewmodel ItemViewModel , ContentControl , Content, , .

, this.ItemViewModel = this.itemViewModel . , .

+9

, . WPF , .

+1

-, , .

  • You can write your own DataTemplateSelector and use it in ContentControl.ContentTemplateSelector and select these two templates accordingly
  • If this view change pattern occurs in many different places and more frequent UX, I would also recommend switching the two views using a DataTemplate.DataTrigger based on a property in SampleViewModel [I assume you can have a distinctive property in ViewModel so that find out this condition]
+1
source

All Articles