Hi,
one approach you can see in following demo (one instance of dataAccess the whole time and edit window as dialog):
XAML Mainwindow:
<Window x:Class="WpfApp1.Window123"
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:WpfApp123"
mc:Ignorable="d"
Title="fatih uyanık_231215" Height="250" Width="400">
<Window.Resources>
<local:ViewModelMain x:Key="vm"/>
</Window.Resources>
<Grid DataContext="{StaticResource vm}" Margin="5">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<DataGrid ItemsSource="{Binding View}" IsReadOnly="True" AutoGenerateColumns="False" Grid.ColumnSpan="2">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding FirstName}"/>
<DataGridTextColumn Binding="{Binding MiddleName}"/>
<DataGridTextColumn Binding="{Binding LastName}"/>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Edit" Command="{Binding CmdEdit, Source={StaticResource vm}}" CommandParameter="{Binding}" Margin="2"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete" Command="{Binding CmdDelete, Source={StaticResource vm}}" CommandParameter="{Binding}" Margin="2"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal" Grid.Row="1" Grid.ColumnSpan="2">
<Button Content="New" Command="{Binding Cmd}" CommandParameter="New" Margin="5"/>
<Button Content="Refresh" Command="{Binding Cmd}" CommandParameter="Refresh" Margin="5"/>
</StackPanel>
</Grid>
</Window>
XAML DetailWindow:
<Window x:Class="WpfApp1.Window123Detail"
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:vm="clr-namespace:WpfApp123"
mc:Ignorable="d"
Title="Window123Sub" Height="200" Width="300"
vm:ViewModelDetail.AttProp="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid DataContext="{Binding View}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="FirstName:" HorizontalAlignment="Right" Margin="5"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding FirstName}" Margin="5"/>
<Label Grid.Row="1" Grid.Column="0" Content="MiddleName:" HorizontalAlignment="Right" Margin="5"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding MiddleName}" Margin="5"/>
<Label Grid.Row="2" Grid.Column="0" Content="LastName:" HorizontalAlignment="Right" Margin="5"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding LastName}" Margin="5"/>
</Grid>
<StackPanel Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Save" Command="{Binding Cmd}" CommandParameter="Save" Margin="5"/>
<Button Content="Delete" Command="{Binding Cmd}" CommandParameter="Delete" Margin="5"/>
<Button Content="Cancel" Command="{Binding Cmd}" CommandParameter="Cancel" Margin="5"/>
</StackPanel>
</Grid>
</Window>
ViewModels:
using System;
using System.ComponentModel;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using WpfApp1;
namespace WpfApp123
{
public class ViewModelMain : INotifyPropertyChanged
{
public ViewModelMain() => refreshData();
private CollectionViewSource cvs = new CollectionViewSource(); // View source for displaying
public ICollectionView View { get => cvs.View; }
private void refreshData()
{
cvs.Source = (new DataAccess()).GetData();
OnPropertyChanged(nameof(View));
}
public ICommand Cmd { get => new RelayCommand(CmdExec); }
private void CmdExec(object obj)
{
switch (obj.ToString())
{
case "Refresh":
refreshData();
break;
case "New":
Window123Tab1 newItem = new Window123Tab1();
CmdEditExec(newItem);
break;
default:
break;
}
}
public ICommand CmdEdit { get => new RelayCommand(CmdEditExec); }
private void CmdEditExec(object obj)
{
Window123Detail wnd = new Window123Detail();
ViewModelDetail vm = new ViewModelDetail();
wnd.DataContext = vm;
DataAccess da = new DataAccess();
Window123Tab1 item = obj as Window123Tab1;
if (item.ID != 0) item = da.Tab1.SingleOrDefault(a => a.ID == item.ID);
if (item != null)
{
vm.View = item;
bool? toSave = wnd.ShowDialog();
if (toSave.Value)
{
if (item.ID == 0) da.AddData(item);
else da.UpdateData(item);
}
else
{
if (item.ID != 0) da.ReloadData(item);
}
}
refreshData();
}
public ICommand CmdDelete { get => new RelayCommand(CmdDeleteExec); }
private void CmdDeleteExec(object obj)
{
Window123Tab1 item = obj as Window123Tab1;
if (item != null) (new DataAccess()).DeleteData(item);
refreshData();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
public class ViewModelDetail
{
public object View { get; set; }
public ICommand Cmd { get => new RelayCommand(CmdExec); }
private void CmdExec(object obj)
{
switch (obj.ToString())
{
case "Save":
SubWindow.DialogResult = true;
SubWindow.Close();
break;
case "Delete":
(new DataAccess()).DeleteData((Window123Tab1)View);
SubWindow.DialogResult = true;
SubWindow.Close();
break;
case "Cancel":
SubWindow.DialogResult = false;
SubWindow.Close();
break;
default:
break;
}
}
public static readonly DependencyProperty AttPropProperty = DependencyProperty.Register("AttProp",
typeof(bool), typeof(Window), new UIPropertyMetadata(false, OnAttProp));
public static bool GetAttProp(DependencyObject obj) => (bool)obj.GetValue(AttPropProperty);
public static void SetAttProp(DependencyObject obj, bool value) => obj.SetValue(AttPropProperty, value);
private static void OnAttProp(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
var wnd = depObj as Window;
if (wnd == null) return;
if ((e.NewValue is bool) && (bool)(e.NewValue))
wnd.Loaded += Wnd_Loaded;
}
private static void Wnd_Loaded(object sender, RoutedEventArgs e)
{
Window wnd = sender as Window;
if (wnd == null) return;
ViewModelDetail dc = wnd.DataContext as ViewModelDetail;
if (dc == null) return;
dc.SubWindow = wnd;
}
Window SubWindow { get; set; }
}
public partial class DataAccess : DbContext
{
public DataAccess() : base("name=Database2Entities") { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Window123Tab1> Tab1 { get; set; }
internal object GetData()=> from item in Tab1.AsEnumerable() select item;
internal void AddData(Window123Tab1 item)
{
Tab1.Add(item);
this.SaveChanges();
}
internal void UpdateData(Window123Tab1 item) => this.SaveChanges();
internal void DeleteData(Window123Tab1 item)
{
Tab1.Remove(Tab1.Single(a => a.ID == item.ID));
this.SaveChanges();
}
internal void ReloadData(Window123Tab1 item)
{
if (this.Entry(item).State != EntityState.Detached)
{
this.Entry(item).State = EntityState.Unchanged;
this.SaveChanges();
}
}
}
public class RelayCommand : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _action;
public RelayCommand(Action<object> action) { _action = action; _canExecute = null; }
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; }
}
}
}
Result: