仅将可观察集合中的可用字母显示到数据网格视图
Displaying only available letters from an observable collection to a datagridview
也许这是一个糟糕的设计理念,但这是我的想法:
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 中填满了所有字母,当用户选择一个字母并为其命名时,该字母不再可用,因此 IsLetterAvailable 设置为 false。
我想在数据网格视图中列出它,但只列出正在使用的字母,即:IsLetterAvailable 设置为 false 的字母,但如果我将 ItemsSource 用于 NetworkDrives,它将列出所有内容。
如果我执行以下操作:
public ObservableCollection<NetworkDrive> UsedNetworkDrives
{
get => NetworkDrives.Where(x => !x.IsLetterAvailable).ToList();
}
然后我失去了通知和能够将字母设置为 true/false 并反映它的能力。
在datagridview中我还有一个关于字母的组合框,这样用户就可以改变它,所以我还需要管理它,以便用过的字母显示为红色,如果选择了用户就不能使用。
有办法解决吗?
如果您不想在视图模型中触及源集合,您可以在视图中使用过滤 CollectionViewSource
:
<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;
也许这是一个糟糕的设计理念,但这是我的想法:
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 中填满了所有字母,当用户选择一个字母并为其命名时,该字母不再可用,因此 IsLetterAvailable 设置为 false。
我想在数据网格视图中列出它,但只列出正在使用的字母,即:IsLetterAvailable 设置为 false 的字母,但如果我将 ItemsSource 用于 NetworkDrives,它将列出所有内容。
如果我执行以下操作:
public ObservableCollection<NetworkDrive> UsedNetworkDrives
{
get => NetworkDrives.Where(x => !x.IsLetterAvailable).ToList();
}
然后我失去了通知和能够将字母设置为 true/false 并反映它的能力。
在datagridview中我还有一个关于字母的组合框,这样用户就可以改变它,所以我还需要管理它,以便用过的字母显示为红色,如果选择了用户就不能使用。
有办法解决吗?
如果您不想在视图模型中触及源集合,您可以在视图中使用过滤 CollectionViewSource
:
<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;