Hi Sarah,
use SaveChange after Dialog like in following demo with your code:
XAML MainWindow:
<Window x:Class="WpfApp1.Window004"
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:WpfApp004"
mc:Ignorable="d"
Title="Sarah-3412_220212_MyContcats" Height="450" Width="1200">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1000"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" ItemsSource="{Binding View}" Margin="5" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding CurrentContact}">
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="CadetBlue" BorderThickness="0,2,0,2" Width="375" Padding="5">
<StackPanel>
<TextBlock Text="{Binding Firstname}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Lastname}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Birthday, StringFormat={}{0:dd/MM/yyyy} }" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Address}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Email}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Phone}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Specialty}" TextWrapping="Wrap"/>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Top" Margin="0,0,0,0">
<Button Height="30" Width="60" Content="Add" Margin="10" Command="{Binding Cmd}" CommandParameter="Add_Click"/>
<Button Height="30" Width="60" Content="Edit" Margin="10" Command="{Binding Cmd}" CommandParameter="Edit_Click"/>
<Button Height="30" Width="60" Content="Remove" Margin="10" Command="{Binding Cmd}" CommandParameter="Remove_Click"/>
</StackPanel>
</Grid>
</Window>
XAML ContactWindow:
<Window x:Class="WpfApp1.Window004A"
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:WpfApp004"
mc:Ignorable="d"
Title="Sarah-3412_220212_Contact" Height="350" Width="400">
<Grid>
<StackPanel DataContext="{Binding CurrentContact}">
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,10,0,10">
<Label Content="Firstname:" Width="120" />
<TextBox Height="25" Width="230" Margin="0,0,5,0" Text="{Binding Path=Firstname}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">
<Label Content="Lastname:" Width="120" />
<TextBox Height="25" Width="230" Margin="0,0,5,0" Text="{Binding Path=Lastname}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">
<Label Content="Birthday:" Width="120" />
<DatePicker x:Name="Birthday" SelectedDateFormat="Short" Height="25" Width="230" FirstDayOfWeek="Monday" IsTodayHighlighted="True" SelectedDate="{Binding Birthday}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">
<Label Content="Address:" Width="120" />
<TextBox Height="25" Width="230" Margin="0,0,5,0" Text="{Binding Path=Address}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">
<Label Content="Phone:" Width="120" />
<TextBox Height="25" Width="230" Margin="0,0,5,0" Text="{Binding Path=Phone}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">
<Label Content="Email:" Width="120" />
<TextBox Height="25" Width="230" Margin="0,0,5,0" Text="{Binding Path=Email}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,0,0,10">
<Label Content="Specialty:" Width="120" />
<ComboBox x:Name="Specialty" Text="{Binding Path=Specialty}" Height="25" Width="230" Margin="0,0,5,0" >
<ComboBoxItem Content="A"/>
<ComboBoxItem Content="B"/>
<ComboBoxItem Content="C"/>
</ComboBox>
</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" Command="{Binding Cmd}" CommandParameter="Close_Click" />
<Button Height="30" Width="70" Content="Save" Margin="10,0,0,0" Command="{Binding Cmd}" CommandParameter="Save_Click" />
</StackPanel>
</Grid>
</Window>
and classes:
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using WpfApp1;
namespace WpfApp004
{
public class ViewModel : FrameworkElement, INotifyPropertyChanged
{
AppDbContext ctx = new AppDbContext();
public ICollectionView View
{
get
{
ctx.tblContact.Load();
cvs.Source = ctx.tblContact.Local.ToObservableCollection();
cvs.View.Refresh();
return cvs.View;
}
}
private CollectionViewSource cvs = new CollectionViewSource();
public ObservableCollection<ContactDetail>? ContactDetails { get; set; }
private ContactDetail _currentContact;
public ContactDetail CurrentContact { get => this._currentContact; set { this._currentContact = value; OnPropertyChanged(nameof(Cmd)); } }
private Window004A addContactWindow;
private bool? ret;
public ICommand Cmd { get { return new RelayCommand(CmdExecute, CmdCanExecute); } }
public event EventHandler? CanExecuteChanged;
public void CmdExecute(object parameter)
{
switch (parameter.ToString())
{
case "Add_Click":
addContactWindow = new Window004A() { DataContext = this };
CurrentContact = new ContactDetail();
ret = addContactWindow.ShowDialog();
if (ret.HasValue && ret.Value) ctx.tblContact.Add(CurrentContact);
else CurrentContact = null;
ctx.SaveChanges();
break;
case "Edit_Click":
if (CurrentContact != null)
{
addContactWindow = new Window004A() { DataContext = this };
ret = addContactWindow.ShowDialog();
if (ret.HasValue && ret.Value) ctx.SaveChanges();
else
{
ctx.Entry(CurrentContact).State = EntityState.Unchanged;
OnPropertyChanged(nameof(View));
}
}
break;
case "Remove_Click":
if (CurrentContact != null) ctx.tblContact.Remove(CurrentContact);
ctx.SaveChanges();
break;
case "Close_Click":
addContactWindow.DialogResult = false;
break;
case "Save_Click":
addContactWindow.DialogResult = true;
break;
default:
break;
}
}
public bool CmdCanExecute(object parameter) =>
((parameter.ToString() != "Edit_Click" && parameter.ToString() != "Remove_Click") || CurrentContact != null);
public event PropertyChangedEventHandler? PropertyChanged;
internal void OnPropertyChanged([CallerMemberName] string name = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public class AppDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) =>
optionsBuilder.UseSqlServer(WpfApp1.Properties.Settings.Default.cnSQL);
public DbSet<ContactDetail> tblContact { get; set; }
}
public class ContactDetail : INotifyPropertyChanged
{
#region private fields
private string _Firstname = String.Empty;
private string _Lastname = String.Empty;
private string _Address = String.Empty;
private string _Phone = String.Empty;
private string _Email = String.Empty;
private DateTime _Birthday = DateTime.Now;
private string _Specialty = String.Empty;
#endregion
#region Properties Getters and Setters
public int ID { get; set; }
public string Firstname
{
get { return _Firstname; }
set { _Firstname = value; OnPropertyChanged(); }
}
public string Lastname
{
get { return _Lastname; }
set { _Lastname = value; OnPropertyChanged(); }
}
public string Address
{
get { return _Address; }
set { _Address = value; OnPropertyChanged(); }
}
public string Phone
{
get { return _Phone; }
set { _Phone = value; OnPropertyChanged(); }
}
public string Email
{
get { return _Email; }
set { _Email = value; OnPropertyChanged(); }
}
public DateTime Birthday
{
get { return _Birthday; }
set { _Birthday = value; OnPropertyChanged(); }
}
public string Specialty
{
get { return _Specialty; }
set { _Specialty = value; OnPropertyChanged(); }
}
#endregion Properties Getters and Setters
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public class RelayCommand : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _action;
public RelayCommand(Action<object> action, Predicate<object> canExecute) { _action = action; _canExecute = canExecute; }
public void Execute(object o) => _action(o);
public bool CanExecute(object o) => _canExecute == null ? true : _canExecute(o);
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
}