How to create Enum and display it in ListView?

Sarah 186 Reputation points
2022-04-12T09:55:31.433+00:00

I have 3 ListViews(MainEnum, SubEnum and SecEnum) in the MainWindow. In the MainEnum are fixed items. I want to do the following:

As an example:

  1. Select Country from MainEnum.
  2. Click "Add" button
  3. Enter France as Country and Paris as City -> France should appear in ListView "SubEnum" and Paris in ListView "SecEnum".

The overview should be as follows:

  1. Select Country -> France, Canada, ect appear in ListView "SubEnum".
  2. Select France -> Paris, Marseille, ect appear in ListView "SecEnum

Delete should be as follows:
1.case: Select Paris -> Only Paris will be deleted
2nd case: Select France-> All cities will be deleted

Edit should be as follows:
1st case: Select Paris -> Only Paris will be changed
2nd case: Select France-> Only France will be changed (cities remain untouched)

Can someone please show me how to implement it? I really have no idea how to do this.

XAML-Code:

<Window x:Class="Enum.MainWindow"
        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:Enum"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions >
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="70"/>
            <ColumnDefinition Width="130"/>
            <ColumnDefinition Width="130"/>
            <ColumnDefinition Width="130"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="150"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <!--Add, modifie and delete buttons-->
        <StackPanel Grid.Row="0" 
                    Grid.Column="0"
                    Orientation="Vertical" 
                    VerticalAlignment="Top" 
                    HorizontalAlignment="Center"
                    Margin="0,40,0,0">
            <Button Content="Add" Width="50" Margin="5"/>
            <Button Content="Edit" Width="50" Margin="5"/>
            <Button Content="Delte" Width="50" Margin="5"/>
        </StackPanel>

        <ListView Grid.Row="0"
                  Grid.Column="1"
                  Margin="0,0,5,0">
            <ListView.View >
                <GridView AllowsColumnReorder="False">
                    <GridViewColumn Header="MainEnum" Width="120">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding }" TextWrapping="Wrap"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
            <ListView.Items >
                <ListViewItem Content="Country"/>
                <ListViewItem Content="Item_X1"/>
                <ListViewItem Content="Item_X2"/>
            </ListView.Items>
        </ListView>

        <ListView Grid.Row="0"
                  Grid.Column="2"
                  Margin="0,0,5,0">
            <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>

        <ListView Grid.Row="0"
                  Grid.Column="3"
                  Margin="0,0,5,0">
            <ListView.View >
                <GridView AllowsColumnReorder="False">
                    <GridViewColumn Header="SecEnum" Width="120">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding SecEnum}" TextWrapping="Wrap"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>

    </Grid>
</Window>

AddEditWindow:

<Window x:Class="Enum.AddEditView"
        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:Enum"
        mc:Ignorable="d"
        Title="AddEditView" Height="200" Width="300">
    <Grid>

        <StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,20,0,0">
            <Label Content="Country:"/>
            <TextBox Width="250"/>
            <Label Content="City:"/>
            <TextBox Width="250"/>
        </StackPanel>

        <StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Bottom" HorizontalAlignment="Center">
            <Button Height="25" Width="60" Content="Cancel" Margin="10"/>
            <Button Height="25" Width="60" Content="Save" Margin="10"/>
        </StackPanel>

    </Grid>
</Window>
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

Accepted answer
  1. Peter Fleischer (former MVP) 19,306 Reputation points
    2022-04-15T04:28:23.937+00:00

    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; }
        }
      }
    }
    

0 additional answers

Sort by: Most helpful