Hi Sarah,
try following demo:
<Window x:Class="WpfApp1.Window015"
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:WpfApp015"
mc:Ignorable="d"
Title="Sarah-3412_220413" Height="450" Width="400">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="130"/>
<ColumnDefinition Width="130"/>
</Grid.ColumnDefinitions>
<!--Add, modifie and delete buttons-->
<StackPanel Grid.Column="0"
Orientation="Vertical"
VerticalAlignment="Top"
HorizontalAlignment="Center"
Margin="0,40,0,0">
<Button Content="Add MainEnum" Margin="5" Command="{Binding Cmd}" CommandParameter="Add_MainEnum"/>
<Button Content="Edit MainEnum" Margin="5" Command="{Binding Cmd}" CommandParameter="Edit_MainEnum"/>
<Button Content="Delete MainEnum" Margin="5" Command="{Binding Cmd}" CommandParameter="Delete_MainEnum"/>
<Button Content="Add SubEnum" Margin="5 20 5 5" Command="{Binding Cmd}" CommandParameter="Add_SubEnum"/>
<Button Content="Edit SubEnum" Margin="5" Command="{Binding Cmd}" CommandParameter="Edit_SubEnum"/>
<Button Content="Delete SubEnum" Margin="5" Command="{Binding Cmd}" CommandParameter="Delete_SubEnum"/>
</StackPanel>
<ListView Grid.Column="1" Margin="0,0,5,0" ItemsSource="{Binding MainEnumView}" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding CurrentMainEnum}">
<ListView.View >
<GridView AllowsColumnReorder="False">
<GridViewColumn Header="MainEnum" Width="120">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding MainEnum}" TextWrapping="Wrap"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<ListView Grid.Column="2" Margin="0,0,5,0" ItemsSource="{Binding SubEnumView}" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding CurrentSubEnum}">
<ListView.View >
<GridView AllowsColumnReorder="False">
<GridViewColumn Header="SubEnum" Width="120">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding SubEnum}" TextWrapping="Wrap"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
----------
<Window x:Class="WpfApp015.Window015A"
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:WpfApp015"
mc:Ignorable="d"
Title="AddEditView" Height="200" Width="300"
WindowStartupLocation="CenterOwner">
<Grid>
<StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,20,0,0">
<Label Content="Country:"/>
<TextBox Width="250" Text="{Binding CurrentData.MainEnum}" IsEnabled="{Binding CurrentData.IsMainEnumEnabled}"/>
<Label Content="City:"/>
<TextBox Width="250" Text="{Binding CurrentData.SubEnum}" IsEnabled="{Binding CurrentData.IsSubEnumEnabled}"/>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center">
<Button Height="25" Width="60" Content="Cancel" Margin="10" Command="{Binding Cmd}" CommandParameter="Cancel"/>
<Button Height="25" Width="60" Content="Save" Margin="10" Command="{Binding Cmd}" CommandParameter="Save"/>
</StackPanel>
</Grid>
</Window>
----------
namespace WpfApp015
{
public class ViewModel : INotifyPropertyChanged
{
private Model m = new Model();
private CollectionViewSource cvsMain = new CollectionViewSource();
public ICollectionView MainEnumView
{
get
{
if (cvsMain.Source == null) cvsMain.Source = m.GetMainEnum();
return cvsMain.View;
}
}
private Data _currentMainEnum;
public Data CurrentMainEnum
{
get => this._currentMainEnum;
set
{
this._currentMainEnum = value;
OnPropertyChanged(nameof(SubEnumView));
OnPropertyChanged(nameof(Cmd));
}
}
private CollectionViewSource cvsSub = new CollectionViewSource();
public ICollectionView SubEnumView
{
get
{
if (cvsSub.Source == null) cvsSub.Source = m.GetSubEnum();
cvsSub.View.Filter = (d) => ((Data)d).FK == CurrentMainEnum?.Id;
return cvsSub.View;
}
}
public Data CurrentSubEnum { get; set; }
private Window015A addEditWindow;
private bool? ret;
public Data CurrentData { get; set; }
public ICommand Cmd { get => new RelayCommand(CmdExecute, CmdCanExecute); }
public void CmdExecute(object? parameter)
{
switch (parameter?.ToString())
{
case "Add_MainEnum":
addEditWindow = new Window015A() { DataContext = this };
CurrentData = new Data() { IsMainEnumEnabled = true };
ret = addEditWindow.ShowDialog();
if (ret.HasValue && ret.Value && !string.IsNullOrEmpty(CurrentData.MainEnum)) m.AddMain(CurrentData);
break;
case "Edit_MainEnum":
addEditWindow = new Window015A() { DataContext = this };
CurrentData = CurrentMainEnum.Copy();
CurrentData.IsMainEnumEnabled = true;
ret = addEditWindow.ShowDialog();
if (ret.HasValue && ret.Value && !string.IsNullOrEmpty(CurrentData.MainEnum))
{ CurrentMainEnum.MainEnum = CurrentData.MainEnum; CurrentMainEnum.OnPropertyChanged(nameof(Data.MainEnum)); }
break;
case "Delete_MainEnum":
m.DeleteMain(CurrentMainEnum); break;
case "Add_SubEnum":
addEditWindow = new Window015A() { DataContext = this };
CurrentData = new Data() { IsSubEnumEnabled = true, MainEnum = CurrentMainEnum.MainEnum, FK = CurrentMainEnum.Id };
ret = addEditWindow.ShowDialog();
if (ret.HasValue && ret.Value && !string.IsNullOrEmpty(CurrentData.SubEnum)) m.AddSub(CurrentData);
break;
case "Edit_SubEnum":
addEditWindow = new Window015A() { DataContext = this };
CurrentData = CurrentSubEnum.Copy();
CurrentData.MainEnum = CurrentMainEnum.MainEnum;
CurrentData.IsSubEnumEnabled = true;
ret = addEditWindow.ShowDialog();
if (ret.HasValue && ret.Value && !string.IsNullOrEmpty(CurrentData.SubEnum))
{ CurrentSubEnum.SubEnum = CurrentData.SubEnum; CurrentSubEnum.OnPropertyChanged(nameof(Data.SubEnum)); }
break;
case "Delete_SubEnum": m.DeleteSub(CurrentSubEnum); break;
case "Save": addEditWindow.DialogResult = true; break;
case "Cancel": addEditWindow.DialogResult = false; break;
default:
break;
}
}
public event EventHandler? CanExecuteChanged;
public bool CmdCanExecute(object? parameter)
{
switch (parameter?.ToString())
{
case "Edit_MainEnum": return CurrentMainEnum != null;
case "Delete_MainEnum": return CurrentMainEnum != null;
case "Edit_SubEnum": return CurrentSubEnum != null;
case "Delete_SubEnum": return CurrentSubEnum != null;
default: return true;
}
}
public event PropertyChangedEventHandler PropertyChanged;
internal void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
internal class Model
{
static int ID;
Random rnd = new Random();
ObservableCollection<Data> colMain = new();
ObservableCollection<Data> colSub = new();
internal ObservableCollection<Data> GetMainEnum()
{
for (int i = 1; i < 10; i++) colMain.Add(new Data() { Id = ID++ + 1, MainEnum = $"Country {ID}" });
return colMain;
}
internal ObservableCollection<Data> GetSubEnum() { for (int i = 1; i < 50; i++) colSub.Add(new Data() { Id = ID++, SubEnum = $"City {ID}", FK = rnd.Next(1, 10) }); return colSub; }
internal void AddMain(Data d) { d.Id = ID++; colMain.Add(d); }
internal void AddSub(Data d) { d.Id = ID++; colSub.Add(d); }
internal void DeleteMain(Data d) { for (int i = colSub.Count - 1; i >= 0; i--) if (colSub[i].FK == d.Id) colSub.Remove(colSub[i]); colMain.Remove(d); }
internal void DeleteSub(Data d) => colSub.Remove(d);
}
public class Data : INotifyPropertyChanged
{
public int Id { get; set; }
public int FK { get; set; }
public string MainEnum { get; set; }
public bool IsMainEnumEnabled { get; set; } = false;
public string SubEnum { get; set; }
public bool IsSubEnumEnabled { get; set; } = false;
public Data Copy() => new Data() { FK = this.FK, MainEnum = this.MainEnum, SubEnum = this.SubEnum };
public event PropertyChangedEventHandler PropertyChanged;
internal void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
public class RelayCommand : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _action;
public RelayCommand(Action<object> action) : this(action, 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; }
}
}
}