Multiple Window (Views/ViewModels) Generation Strategy

scott thomson 66 Reputation points
2021-02-23T00:54:37.02+00:00

I am using C#, .Net WPF and MVVM approach

What would be a recommended strategy/Design for the situation were I have a MainWindow view and associated viewmodel and wish to "open" another such window for the user which will display another objects values. For example they are viewing an objects values via mainwindow then go into a search feature where they find another object for which they want to view its values. they click on this in the list and a view appears showing that objects values. they then can close this view and return to the original view with the original object.

First I have at least 2 choices Im aware of I can begin with. Use the existing MainWindow view and viewmodel for the new object as they are exactly the same or 99% same and need to use same view/viewmodel functionality or write a (almost) copy of the mainwindow view/viewmodel and show this one. The second option will require more maintenance because I have to duplicate any changes across both but can make other things easier and maybe cleaner.

So whats best approach for this issue?

The next decision to make is how to do this? I have so far considered the following ways to do the "showing" of the new view and selected objects data.;

  1. set up datatemplates in the mainwindow and swap the views in and out (ie triggered by xaml button command bound to viewmodel)
  2. instantiate a new instance of MainWindow view and mainwindowviewmodel using .ShowDialog in code (ie triggered by xaml button command bound to viewmodel)
  3. Set up a view factory instead of instantiating in code

In all cases I need to pass a parameter to the newly shown View or Dialog that is used by its ViewModel to retrieve from database and show the required object.

thanks Scott

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,700 questions
{count} votes

1 answer

Sort by: Most helpful
  1. DaisyTian-1203 11,616 Reputation points
    2021-02-24T09:08:45.933+00:00

    I make a demo on my understanding for your question, please check if I misunderstand. If I misunderstand, could you please give an operation result diagram to anlayze?
    The ViewModel is:

    class PersonViewModel:NotifyObject  
        {  
            private PersonModel userEdit;  
            public PersonModel UserEdit  
            {  
                get { return userEdit; }  
                set  
                {  
                    userEdit = value;  
                    OnPropertyChange("UserEdit");  
                }  
            }  
      
            private ObservableCollection<PersonModel> ltPersons = new ObservableCollection<PersonModel>();  
            public ObservableCollection<PersonModel> LtPersons  
            {  
                get { return ltPersons; }  
                set  
                {  
                    this.ltPersons = value;  
                    OnPropertyChange("LtPersons");  
                }  
            }  
      
            public PersonViewModel()  
            {  
                LtPersons = new ObservableCollection<PersonModel>() {   
                    new PersonModel { Name = "John1", Age = 11, Pass=false,Email= new Uri("mailto:JOE+@school.com") },   
                    new PersonModel { Name = "John2", Age = 12 , Pass=false,Email= new Uri("mailto:JOE+@school.com")},   
                    new PersonModel { Name = "John3", Age = 13 , Pass=false,Email= new Uri("mailto:JOE+@school.com")} };  
            }  
      
            public ICommand ButtonCommand  
            {  
                get  
                {  
                    return new DelegateCommand<PersonModel>((model) =>   
                    {  
                        UpdateUser updateUser = new UpdateUser();  
                        updateUser.DataContext = model;  
                        updateUser.Show();  
                    });  
                }  
            }             
        }  
    

    The MainWindow is:

      <Window.DataContext>  
            <local:PersonViewModel></local:PersonViewModel>  
        </Window.DataContext>  
      
        <Grid Width="800" Height="250" HorizontalAlignment="Left" >  
            <DataGrid Width="200" Height="200"  
                      x:Name="dataGrid"   
                      HorizontalAlignment="Left"  
                      ItemsSource="{Binding LtPersons}"   
                      AutoGenerateColumns="False"    
                      SelectionMode="Extended"   
                      SelectionUnit="FullRow"   
                      SelectedItem="{Binding UserEdit}"  
                      >  
                <DataGrid.Columns>  
                    <DataGridTextColumn Header="Name" Width="80" Binding="{Binding Name,Mode=TwoWay}"/>  
                    <DataGridTextColumn Header="Age" Width="50" Binding="{Binding Age,Mode=TwoWay}" />  
                </DataGrid.Columns>  
            </DataGrid>  
            <Button Height="18" Width="50" Content="Query" Command="{Binding ButtonCommand}" CommandParameter="{Binding UserEdit}" />  
        </Grid>  
    

    The UpdateWindow is:

     <Grid >  
            <Grid.ColumnDefinitions>  
                <ColumnDefinition Width="100"/>  
                <ColumnDefinition Width="*"/>  
            </Grid.ColumnDefinitions>  
            <Grid.RowDefinitions>  
                <RowDefinition Height="Auto"/>  
                <RowDefinition Height="Auto"/>  
                <RowDefinition Height="Auto"/>  
                <RowDefinition Height="Auto"/>  
                <RowDefinition Height="Auto"/>  
                <RowDefinition Height="300"/>  
            </Grid.RowDefinitions>  
            <Label Grid.Row="0" Grid.Column="0" Content="Name"  HorizontalAlignment="Right" ></Label>  
            <TextBox Grid.Row="0" Grid.Column="1" Margin="4" Text="{Binding Name,Mode=TwoWay}" />  
            <Label  Grid.Row="1" Grid.Column="0" Content="Age:" HorizontalAlignment="Right"/>  
            <TextBox  Grid.Row="1" Grid.Column="1" Margin="4" Text="{Binding Age,Mode=TwoWay}"/>  
            <Label Grid.Row="2" Grid.Column="0" Content="Mail:" HorizontalAlignment="Right"/>  
            <TextBox  Grid.Row="2" Grid.Column="1" Margin="4" Text="{Binding Email,Mode=TwoWay}"/>  
            <Label Grid.Row="3"  Grid.Column="0"  Content="Pass:" HorizontalAlignment="Right"/>  
            <TextBox Grid.Row="3" Grid.Column="1"  Margin="4" Text="{Binding Pass,Mode=TwoWay}" />  
            <Button  Grid.Row="4" Grid.Column="0" Content="Save" Click="Button_Click" ></Button>  
      
        </Grid>  
    

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.