Hello! Suppose there are two views. View1 appears when the form is loaded, and View2 by clicking on the button. How can I make it so that when View2 View1 disappears? At the moment I have View2, but View1 remains to hang and appear through View2 Example

Views are bind as follows: MainWindow.xaml

<Window.Resources> <DataTemplate x:Name="v1" DataType="{x:Type viewmodels:View1ViewModel}"> <views:View1 DataContext="{Binding}"/> </DataTemplate> <DataTemplate x:Name="v2" DataType="{x:Type viewmodels:View2ViewModel}"> <views:View2 DataContext="{Binding}"/> </DataTemplate> </Window.Resources> <Grid> <ContentControl Content="{Binding}"/> </Grid> 

View1 is bound

 <ContentControl Content="{Binding View2}"/> 

By pressing the button the command is triggered.

 private RelayCommand showView2; public RelayCommand ShowView2 { get { return showView2 ?? (showView2= new RelayCommand(obj => { View2Form = new View2ViewModel(); })); } } 

View2 property to be displayed

 private object view2Form; public object View2Form { get { return view2Form; } set { if (Equals(view2Form, value)) return; view2Form= value; OnPropertyChanged("View2Form"); } } 
  • View1 has a binding <ContentControl Content = "{Binding View2Form }" /> - Dmitry Bystrov
  • some kind of tangled code - user227049
  • Not sure I understand what you want to implement? something like navigation? - user227049

1 answer 1

Well, you almost did everything right, changing the View through ContentControl is a good, right way. You just did not stretch the command in View1, and therefore include View2 not where you want: at the View2 level, and not at the root VM level.

Here are sketches of how it should be.

To begin with, VM for the first and second View.

 class View1ViewModel { public View1ViewModel(ICommand showView2) { ShowView2 = showView2; } public ICommand ShowView2 { get; } } class View2ViewModel { } 

View1ViewModel should set the transition command to the second View.

Now, the main VM. I wrote a standard implementation of INotifyPropertyChanged (you should, in theory, have it in the parent class). And also renamed View2Form to SubViewModel . I give the VM change command to View1ViewModel in the constructor ( View1ViewModel itself cannot create this command, View1ViewModel this command should change the properties of the main VM!).

 class MainVM : INotifyPropertyChanged { public MainVM() { ShowView2 = new RelayCommand(obj => SubViewModel = new View2ViewModel()); SubViewModel = new View1ViewModel(ShowView2); } public event PropertyChangedEventHandler PropertyChanged; private object subViewModel; public object SubViewModel { get { return subViewModel; } set { if (Equals(subViewModel, value)) return; subViewModel = value; OnPropertyChanged(); } } protected void OnPropertyChanged([CallerMemberName]string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); public ICommand ShowView2 { get; } } 

View1 looks simple:

 <Button Command="{Binding ShowView2}" HorizontalAlignment="Center" VerticalAlignment="Center" Content="Show View 2"/> 

And View2 :

 <TextBlock TextAlignment="Center" VerticalAlignment="Center" Text="I am View 2"/> 

The main window is almost unchanged (only binding to SubViewModel ):

 <Window.Resources> <DataTemplate DataType="{x:Type viewmodels:View1ViewModel}"> <views:View1 DataContext="{Binding}"/> </DataTemplate> <DataTemplate DataType="{x:Type viewmodels:View2ViewModel}"> <views:View2 DataContext="{Binding}"/> </DataTemplate> </Window.Resources> <Grid> <ContentControl Content="{Binding SubViewModel}"/> </Grid> 

Result:

animated cartoon

  • Everything worked out! And tell me that if I want the command that is written in View1ViewModel to be executed on the "Show View 2" button. It’s just that some properties change, which work only for View1, I don’t want to transfer everything to MainVM - Dmitry Bystrov
  • Ie, I click on "show second view", first my main command is executed, and if successful, the second view opens, and in case of failure, some properties for the first view, written in View1ViewModel and linked to View1, change - Dmitry Bystrov
  • @ Bystrov Dmitry: Then you should still send the transition command (denoted by # 1) from MainVM, and in View1ViewModel, define your command # 2, which will perform what you need, and then pull command # 1 (that is, call Execute her) And then to the button you need to bind the command number 2. - VladD
  • Could you give an example of how to do this? - Dmitry Bystrov
  • @ Bystrov Dmitry: And what exactly is not clear for you? How to define a new team? How to attach a button to it? - VladD