How to update listView using MVVM pattern and ObservableCollection in WPF?

Imilio 41 Reputation points
2022-01-11T20:39:56.773+00:00

I want to update a listview in UserControl included in MainWindow when adding/removing an entry over opening a Window.
When clicking the save button, nothing happens
Can anyone please help me to see, what I'm doing wrong?

Best regards
Imilio

What I have done:

XAML - MainWindow

<Window x:Class="Add_Edit_Delete.ucWindow.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Add_Edit_Delete.ucWindow" xmlns:local1="clr-namespace:Add_Edit_Delete.ViewModel"
        mc:Ignorable="d"
        Title="Window1" Height="450" Width="400">

    <Window.DataContext>
        <local1:AddViewModel/>
    </Window.DataContext>

    <Grid>
        <StackPanel>

            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">
                <Label Content="Firstname:" Width="120" />
                <TextBox x:Name="tbFirstname" Height="25" Width="230" Margin="0,0,5,0" Text="{Binding NewUser.Firstname}"/>
            </StackPanel>

            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">
                <Label Content="Firstname:" Width="120" />
                <TextBox x:Name="tbLastname" Height="25" Width="230" Margin="0,0,5,0" Text="{Binding NewUser.Lastname}"/>
            </StackPanel>



        </StackPanel>

        <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="10,0,10,10">
            <Button Height="30" Width="70" Content="Close" Margin="10,0,0,0"/>
            <Button Height="30" Width="70" Content="Save" Margin="10,0,0,0" Command="{Binding AddUserCommand}"/>
        </StackPanel>
    </Grid>
</Window>

C# - MainWindow

using Add_Edit_Delete.Usercontrol;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Add_Edit_Delete
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void User_Click(object sender, RoutedEventArgs e)
        {
            UserControl1 oUser = new UserControl1();
            Grid.SetColumn(oUser, 1);
            MainGrid.Children.Add(oUser);
        }
    }
}

XAML - UserControl1

<UserControl x:Class="Add_Edit_Delete.Usercontrol.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Add_Edit_Delete.Usercontrol" xmlns:local1="clr-namespace:Add_Edit_Delete.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800" Background="White">

    <UserControl.DataContext>
        <local1:UserViewModel/>
    </UserControl.DataContext>

    <Grid>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <ListView Grid.Column="0">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Firstname" x:Name="Firstname" Width="200">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Firstname}" TextWrapping="Wrap"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Lastname" x:Name="Lastname" Width="200">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Lastname}" TextWrapping="Wrap"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>


        <StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Top" Margin="20,0,0,0">

            <Button Height="25" Width="50" Content="Add" Margin="10" Click="Add_Click"/>
            <Button Height="25" Width="50" Content="Edit" Margin="10" Click="Eddit_Click"/>
            <Button Height="25" Width="50" Content="Delete" Margin="10" Click="Delete_Click" /> 

        </StackPanel>

    </Grid>
</UserControl>

C# - UserControl1

    using Add_Edit_Delete.ucWindow;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    namespace Add_Edit_Delete.Usercontrol
    {
        /// <summary>
        /// Interaktionslogik für UserControl1.xaml
        /// </summary>
        public partial class UserControl1 : UserControl
        {
            public UserControl1()
            {
                InitializeComponent();
            }


            private void Delete_Click(object sender, RoutedEventArgs e)
            {

            }

            private void Eddit_Click(object sender, RoutedEventArgs e)
            {

            }

            private void Add_Click(object sender, RoutedEventArgs e)
            {
                Window1 oAdd = new Window1();
                oAdd.Owner = Application.Current.MainWindow;
                oAdd.ShowDialog();
            }
        }
    }


**XAML - Window1**


<Window x:Class="Add_Edit_Delete.ucWindow.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Add_Edit_Delete.ucWindow" xmlns:local1="clr-namespace:Add_Edit_Delete.ViewModel"
        mc:Ignorable="d"
        Title="Window1" Height="450" Width="400">

    <Window.DataContext>
        <local1:AddViewModel/>
    </Window.DataContext>

    <Grid>
        <StackPanel>

            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">
                <Label Content="Firstname:" Width="120" />
                <TextBox x:Name="tbFirstname" Height="25" Width="230" Margin="0,0,5,0" Text="{Binding NewUser.Firstname}"/>
            </StackPanel>

            <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">
                <Label Content="Firstname:" Width="120" />
                <TextBox x:Name="tbLastname" Height="25" Width="230" Margin="0,0,5,0" Text="{Binding NewUser.Lastname}"/>
            </StackPanel>



        </StackPanel>

        <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="10,0,10,10">
            <Button Height="30" Width="70" Content="Close" Margin="10,0,0,0"/>
            <Button Height="30" Width="70" Content="Save" Margin="10,0,0,0" Command="{Binding AddUserCommand}"/>
        </StackPanel>
    </Grid>
</Window>

C# - Window1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Add_Edit_Delete.ucWindow
{
    /// <summary>
    /// Interaktionslogik für Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
    }
}

UserModel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Add_Edit_Delete.Model
{
    class UserModel
    {
        public int Id { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }
    }
}

AddViewModel

using Add_Edit_Delete.Commands;
using Add_Edit_Delete.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Add_Edit_Delete.ViewModel
{
    class AddViewModel : INotifyPropertyChanged
    {
        public AddViewModel()
        {
            this.AddUserCommand = new DelegateCommand((o) =>
            {
                this.ListOfUser.Add(NewUser);
            });
        }

        UserModel newUser = new UserModel();
        public UserModel NewUser
        {
            get => newUser;
            set
            {
                if (newUser != value)
                {
                    newUser = value;
                    this.RaisePropertyChanged(nameof(NewUser));
                }
            }
        }

        private ObservableCollection<UserModel> listOfUser = new ObservableCollection<UserModel>();
        public ObservableCollection<UserModel> ListOfUser
        {
            get => listOfUser;
            set
            {
                if (listOfUser != value)
                {
                    listOfUser = value;
                    this.RaisePropertyChanged(nameof(ListOfUser));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public DelegateCommand AddUserCommand { get; set; }
    }
}

UserViewModel

using Add_Edit_Delete.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Add_Edit_Delete.ViewModel 
{
    class UserViewModel : INotifyPropertyChanged
    {
        UserModel newUser = new UserModel();
        public UserModel NewUser
        {
            get => newUser;
            set
            {
                if (newUser != value)
                {
                    newUser = value;
                    this.RaisePropertyChanged(nameof(NewUser));
                }
            }
        }

        private ObservableCollection<UserModel> listOfUser = new ObservableCollection<UserModel>();
        public ObservableCollection<UserModel> ListOfUser
        {
            get => listOfUser;
            set
            {
                if (listOfUser != value)
                {
                    listOfUser = value;
                    this.RaisePropertyChanged(nameof(ListOfUser));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

DelegationCommand

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Add_Edit_Delete.Commands
{
    public class DelegateCommand : ICommand
    {


        readonly Action<object> execute;

        readonly Predicate<object> canExecute;

        public DelegateCommand(Predicate<object> canExecute, Action<object> execute) =>
            (this.canExecute, this.execute) = (canExecute, execute);

        public DelegateCommand(Action<object> execute) : this(null, execute) { }


        public event EventHandler CanExecuteChanged;


        public void RaiseCanExecuteChanged() => this.CanExecuteChanged?.Invoke(this, EventArgs.Empty);


        public bool CanExecute(object parameter) => this.canExecute?.Invoke(parameter) ?? true; 

        public void Execute(object parameter) => this.execute?.Invoke(parameter);
    }
}

The project can be downloaded here

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,676 questions
0 comments No comments
{count} votes

10 answers

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2022-01-12T06:18:09.037+00:00

    Hi,
    you add UserModel to ListOfUser in AddViewModel and show ListOfUser from UserViewModel. That are different lists.

    1 person found this answer helpful.

  2. Hui Liu-MSFT 40,266 Reputation points Microsoft Vendor
    2022-01-13T08:47:29.567+00:00

    As Peter said ,you could delete the DataContext in the xaml of Window1 and UserControl1. Then modify the code of UserControl1 as follows.

    public partial class UserControl1 : UserControl  
         {  
             AddViewModel vm = new AddViewModel();  
             public UserControl1()  
             {  
                 InitializeComponent();  
                 this.DataContext=vm;  
             }  
         private void Add_Click(object sender, RoutedEventArgs e)  
             {  
                 Window1 oAdd = new Window1();  
                  oAdd.DataContext=vm;  
                 oAdd.Owner = Application.Current.MainWindow;  
                 oAdd.ShowDialog();  
             }  
         }  
    

    Then bind the ItemsSource for the ListView .
    UserControl1.xaml:

     <ListView Grid.Column="0" ItemsSource="{Binding ListOfUser}">  
                <ListView.View>  
                    <GridView>  
                        <GridViewColumn Header="Firstname" x:Name="Firstname" Width="200">  
                            <GridViewColumn.CellTemplate>  
                                <DataTemplate>  
                                    <TextBlock Text="{Binding Firstname}" TextWrapping="Wrap"/>  
                                </DataTemplate>  
                            </GridViewColumn.CellTemplate>  
                        </GridViewColumn>  
                        <GridViewColumn Header="Lastname" x:Name="Lastname" Width="200">  
                            <GridViewColumn.CellTemplate>  
                                <DataTemplate>  
                                    <TextBlock Text="{Binding Lastname}" TextWrapping="Wrap"/>  
                                </DataTemplate>  
                            </GridViewColumn.CellTemplate>  
                        </GridViewColumn>  
                    </GridView>  
                </ListView.View>  
            </ListView>  
    

    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.


  3. Peter Fleischer (former MVP) 19,231 Reputation points
    2022-01-13T16:51:46.32+00:00

    Hi,
    you can simplified your code like this:

    MainWindow:

    <Window x:Class="WpfApp1.Window094"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:local="clr-namespace:WpfApp1"  
            xmlns:local1="clr-namespace:WpfControlLibrary094.Add_Edit_Delete.ViewModel;assembly=WpfControlLibrary1"  
            xmlns:uc="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"  
            mc:Ignorable="d"  
            Title="Imilio-3053_220112" Height="450" Width="800">  
      <Grid>  
        <StackPanel>  
         <uc:Window094UC1 Margin="5"/>  
        </StackPanel>  
      </Grid>  
    </Window>  
    

    XAML UserControl:

    <UserControl x:Class="WpfControlLibrary1.Window094UC1"  
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"   
                 xmlns:local="clr-namespace:WpfControlLibrary1"  
                 xmlns:local1="clr-namespace:WpfControlLibrary094.Add_Edit_Delete.ViewModel"  
                 mc:Ignorable="d"   
                 d:DesignHeight="450" d:DesignWidth="800">  
      <UserControl.DataContext>  
        <local1:UserViewModel/>  
      </UserControl.DataContext>  
      <Grid>  
        <Grid.ColumnDefinitions>  
          <ColumnDefinition Width="*"/>  
          <ColumnDefinition Width="*"/>  
        </Grid.ColumnDefinitions>  
        <ListView Grid.Column="0" ItemsSource="{Binding ListOfUser}">  
          <ListView.View>  
            <GridView>  
              <GridViewColumn Header="Firstname" x:Name="Firstname" Width="200">  
                <GridViewColumn.CellTemplate>  
                  <DataTemplate>  
                    <TextBlock Text="{Binding Firstname}" TextWrapping="Wrap"/>  
                  </DataTemplate>  
                </GridViewColumn.CellTemplate>  
              </GridViewColumn>  
              <GridViewColumn Header="Lastname" x:Name="Lastname" Width="200">  
                <GridViewColumn.CellTemplate>  
                  <DataTemplate>  
                    <TextBlock Text="{Binding Lastname}" TextWrapping="Wrap"/>  
                  </DataTemplate>  
                </GridViewColumn.CellTemplate>  
              </GridViewColumn>  
            </GridView>  
          </ListView.View>  
        </ListView>  
        <StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Top" Margin="20,0,0,0">  
          <Button Height="25" Width="50" Content="Add" Margin="10" Command="{Binding Cmd}" CommandParameter="Add_Click"/>  
          <Button Height="25" Width="50" Content="Edit" Margin="10" Command="{Binding Cmd}" CommandParameter="Eddit_Click"/>  
          <Button Height="25" Width="50" Content="Delete" Margin="10" Command="{Binding Cmd}" CommandParameter="Delete_Click" />  
        </StackPanel>  
      </Grid>  
    </UserControl>  
    

    XAML Window1:

    <Window x:Class="WpfControlLibrary1.Window094A"  
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
            xmlns:local="clr-namespace:WpfControlLibrary1"  
            xmlns:local1="clr-namespace:WpfControlLibrary094.Add_Edit_Delete.ViewModel"  
            mc:Ignorable="d"  
            Title="Window1" Height="150" Width="400">  
      <Grid>  
        <StackPanel>  
          <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">  
            <Label Content="Firstname:" Width="120" />  
            <TextBox x:Name="tbFirstname" Height="25" Width="230" Margin="0,0,5,0" Text="{Binding NewUser.Firstname}"/>  
          </StackPanel>  
          <StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">  
            <Label Content="Firstname:" Width="120" />  
            <TextBox x:Name="tbLastname" Height="25" Width="230" Margin="0,0,5,0" Text="{Binding NewUser.Lastname}"/>  
          </StackPanel>  
        </StackPanel>  
        <StackPanel Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="10,0,10,10">  
          <Button Height="30" Width="70" Content="Close" Margin="10,0,0,0"/>  
          <Button Height="30" Width="70" Content="Save" Margin="10,0,0,0" Command="{Binding AddUserCommand}"/>  
        </StackPanel>  
      </Grid>  
    </Window>  
    

    Code:

    using System;  
    using System.Collections.ObjectModel;  
    using System.ComponentModel;  
    using System.Windows;  
    using System.Windows.Controls;  
    using System.Windows.Input;  
    using WpfControlLibrary094.Add_Edit_Delete.Commands;  
    using WpfControlLibrary1;  
    
    namespace WpfControlLibrary094.Add_Edit_Delete.ViewModel  
    {  
      public class UserModel  
      {  
        static int number = 1;  
        public int Id { get; set; }  
        public string Firstname { get; set; }  
        public string Lastname { get; set; }  
        public UserModel Copy() => new UserModel() { Id = number++, Firstname = this.Firstname, Lastname = this.Lastname };  
      }  
      
      public class UserViewModel : INotifyPropertyChanged  
      {  
        public UserViewModel() => this.AddUserCommand = new DelegateCommand((o) => { this.ListOfUser.Add(NewUser.Copy()); });  
        public DelegateCommand AddUserCommand { get; set; }  
      
        public UserModel NewUser { get; set; } = new UserModel();  
      
        public ObservableCollection<UserModel> ListOfUser { get; set; } = new ObservableCollection<UserModel>();  
      
        public ICommand Cmd { get => new DelegateCommand(null, CmdExec); }  
      
        private void CmdExec(object obj)  
        {  
          switch (obj.ToString())  
          {  
            case "Add_Click":  
              Window094A oAdd = new Window094A();  
              oAdd.DataContext = this;  
              oAdd.Owner = Application.Current.MainWindow;  
              oAdd.ShowDialog();  
              break;  
            default:  
              break;  
          }  
        }  
      
        public event PropertyChangedEventHandler PropertyChanged;  
        private void RaisePropertyChanged(string propertyName) =>  
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));  
      }  
    }  
      
    namespace WpfControlLibrary094.Add_Edit_Delete.Commands  
    {  
      public class DelegateCommand : ICommand  
      {  
        readonly Action<object> execute;  
        readonly Predicate<object> canExecute;  
        public DelegateCommand(Predicate<object> canExecute, Action<object> execute) =>  
          (this.canExecute, this.execute) = (canExecute, execute);  
        public DelegateCommand(Action<object> execute) : this(null, execute) { }  
        public event EventHandler CanExecuteChanged;  
        public void RaiseCanExecuteChanged() => this.CanExecuteChanged?.Invoke(this, EventArgs.Empty);  
        public bool CanExecute(object parameter) => this.canExecute?.Invoke(parameter) ?? true;  
        public void Execute(object parameter) => this.execute?.Invoke(parameter);  
      }  
    }  
    

    Result:

    164871-x.gif


  4. Imilio 41 Reputation points
    2022-01-14T19:47:18.967+00:00

    Hi @Peter Fleischer (former MVP) , your code works correctly. What am I doing wrong that I overwrite the previous items with the new one? I would like to avoid the copy method.
    I would like to separate the contents of Usercontrol1 and Window1. as follows:

    UserViewModel:

       using System.ComponentModel;  
        using System.Linq;  
        using System.Text;  
        using System.Threading.Tasks;  
        using System.Windows;  
        using System.Windows.Input;  
        using WPF_App.Commands;  
        using WPF_App.Model;  
        using WPF_App.ucWindow;  
          
        namespace WPF_App.ViewModel  
        {  
            public class UserViewModel  
            {  
                public ICommand Cmd { get => new DelegateCommand(null, CmdExec); }  
          
                private void CmdExec(object obj)  
                {  
                    switch (obj.ToString())  
                    {  
                        case "Add_Click":  
                            Window1 oAdd = new Window1();  
                            oAdd.DataContext = this;  
                            oAdd.Owner = Application.Current.MainWindow;  
                            oAdd.ShowDialog();  
                            break;  
                        case "Edit_Click":  
                            //TBD  
                            break;  
                        case "Delete_Click":  
                            //TBD  
                            break;  
                        default:  
                            break;  
                    }  
                }  
            }  
        }  
    

    AddViewModel:

    using System.Threading.Tasks;  
    using System.Windows;  
    using System.Windows.Input;  
    using WPF_App.Commands;  
    using WPF_App.Model;  
    using WPF_App.ucWindow;  
      
    namespace WPF_App.ViewModel  
    {  
        public class AddViewModel : INotifyPropertyChanged  
        {  
            public AddViewModel() => this.AddUserCommand = new DelegateCommand((o) => { this.ListOfUser.Add(NewUser.Copy()); });  
            public DelegateCommand AddUserCommand { get; set; }  
      
            public UserModel NewUser { get; set; } = new UserModel();  
      
            public ObservableCollection<UserModel> ListOfUser { get; set; } = new ObservableCollection<UserModel>();  
      
            public event PropertyChangedEventHandler PropertyChanged;  
            private void RaisePropertyChanged(string propertyName) =>  
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));  
        }  
    }  
    

    if I do that, I have the original problem again. Nothing happens when I click on the Save button!


  5. Peter Fleischer (former MVP) 19,231 Reputation points
    2022-01-15T05:39:06.327+00:00

    Hi,
    if you need to use separate ViewModels for UserControl and Window1 try this code:

    namespace Add_Edit_Delete.ViewModel
    {
      public class UserModel
      {
        public int Id { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }
      }
    
      public class UserViewModel : INotifyPropertyChanged
      {
        public ObservableCollection<UserModel> ListOfUser { get; set; } = new ObservableCollection<UserModel>();
        public ICommand Cmd { get => new DelegateCommand(null, CmdExec); }
    
        private void CmdExec(object obj)
        {
          switch (obj.ToString())
          {
            case "Add_Click":
              Window094A oAdd = new Window094A();
              AddViewModel vm = new AddViewModel(this);
              oAdd.DataContext = vm;
              oAdd.Owner = Application.Current.MainWindow;
              oAdd.ShowDialog();
              break;
            default:
              break;
          }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string propertyName) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      }
    
      public class AddViewModel : INotifyPropertyChanged
      {
        public AddViewModel(UserViewModel vm)
        {
          mainVm = vm;
          this.AddUserCommand = new DelegateCommand((o) =>
          {
            mainVm.ListOfUser.Add(NewUser);
            NewUser = new UserModel();
            RaisePropertyChanged(nameof(NewUser));
          });
        }
        public DelegateCommand AddUserCommand { get; set; }
    
        private UserViewModel mainVm;
    
        public UserModel NewUser { get; set; } = new UserModel();
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void RaisePropertyChanged(string propertyName) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      }
    }
    
    0 comments No comments