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;