Home > other >  Displaying only available letters from an observable collection to a datagridview
Displaying only available letters from an observable collection to a datagridview

Time:09-26

Maybe this is a bad design idea, but this is what I had in mind:

public class NetworkDrive : BaseNotify
{
    private char letter;
    public char Letter
    {
        get => letter;
        set => SetAndNotify(ref letter, value, nameof(Letter));
    }

    private string name;
    public string Name
    {
        get => name;
        set => SetAndNotify(ref name, value, nameof(Letter));
    }

    private bool isLetterAvailable;
    public bool IsLetterAvailable
    {
        get => isLetterAvailable;
        set => SetAndNotify(ref isLetterAvailable, value, nameof(Letter));
    }
}

public class EditDriveViewModel : Screen
{
    public ObservableCollection<NetworkDrive> NetworkDrives { get; } = new();

}

NetworkDrives is filled with all the alphabet letters and when the user selects a letter and names it, the letter is no longer available so IsLetterAvailable is set to false.

I would like to list it in a datagridview but only the letters that are in use, i.e.: letters with IsLetterAvailable set to false, but if I use ItemsSource to NetworkDrives it will list everything.

If I do something like the below:

public ObservableCollection<NetworkDrive> UsedNetworkDrives
{
    get => NetworkDrives.Where(x => !x.IsLetterAvailable).ToList();
}

Then I lose notifications and the ability of being able to set a letter to true/false and have it reflected.

In the datagridview I also have a combobox on letter, so that the user can change it, so I also need to manage it so that used letters are displayed in red and the user cannot use then if selected.

Is there a way to solve this?

CodePudding user response:

If you don't want to touch the source collection in the view model, you could use a filtered CollectionViewSource in the view:

<Window.Resources>
    <CollectionViewSource x:Key="cvs" Source="{Binding NetworkDrives}"
                              Filter="CollectionViewSource_Filter"
                              IsLiveFilteringRequested="True"
                              xmlns:s="clr-namespace:System;assembly=mscorlib">
        <CollectionViewSource.LiveFilteringProperties>
            <s:String>IsLetterAvailable</s:String>
        </CollectionViewSource.LiveFilteringProperties>
    </CollectionViewSource>
</Window.Resources>
...
<ComboBox x:Name="cmb"
          ItemsSource="{Binding Source={StaticResource cvs}}"
          DisplayMemberPath="Name" />

    private void CollectionViewSource_Filter(object sender, FilterEventArgs e) =>
        e.Accepted = e.Item is NetworkDrive networkDrive
          && networkDrive.IsLetterAvailable;
  • Related