gpt4 book ai didi

c# - 使用 Josh Smith 的 WPF MVVM 演示应用程序实现 ListView 筛选器

转载 作者:太空狗 更新时间:2023-10-29 22:12:26 25 4
gpt4 key购买 nike

我一直在尝试扩展 Josh Smith 的演示 MVVM 应用程序,以便更好地理解其背后的原理,但在尝试使用 ListView 在 View 上实现过滤器功能时,我遇到了困难。

我花了几个小时研究和尝试,但它就是行不通。

我的第一步是将 View 中的文本框绑定(bind)到 ViewModel 中的属性:

<TextBox Height="25" Name="txtFilter" Width="150" Text="{Binding Path=Filter, UpdateSourceTrigger=PropertyChanged}"/>

这在我的 VM 中匹配:

public string Filter
{
get { return this.filter; }
set
{
this.filter = value;
OnFilterChanged();
}
}

我的 VM 使用 ObservableCollection 作为数据源,但我在阅读教程后尝试将其转换为 ICollectionView:

internal ObservableCollection<StaffViewModel> InnerStaff { get; set; }
internal CollectionViewSource CvsStaff { get; set; }
public ICollectionView AllStaff
{
get { return CvsStaff.View; }
}

在我的构造函数中我指定了:

CvsStaff = new CollectionViewSource();
CvsStaff.Source = this.InnerStaff;
CvsStaff.Filter += ApplyFilter;

当我的 Filter 属性更新时,它会调用 OnFilterChanged,它是:

private void OnFilterChanged()
{
CvsStaff.View.Refresh();
}

我的 ApplyFilter 函数是:

void ApplyFilter(object sender, FilterEventArgs e)
{
StaffViewModel svm = (StaffViewModel)e.Item;

if (this.Filter.Length == 0)
{
e.Accepted = true;
}
else
{
e.Accepted = svm.LastName.Contains(Filter);
}
}

是否有任何人可以帮助我发现的愚蠢错误?我对 WPF 和 MVVM 模式还很陌生,所以我还在学习!

编辑

在我绑定(bind)集合的 View 中:

<CollectionViewSource
x:Key="StaffGroup"
Source="{Binding Path=AllStaff}"
/>

ListView 是这样的:

<ListView
Name="staffList"
AlternationCount="2"
DataContext="{StaticResource StaffGroup}"
ItemContainerStyle="{StaticResource StaffItemStyle}"
ItemsSource="{Binding}"
Grid.Row="1">

最佳答案

绑定(bind)不正确。您需要进行一些更改。首先要确保 DataContext 设置正确。通常,您将在 ListView 的父级上执行此操作,而不是直接在 ListView 控件上设置它。这可能是一个 UserControl/Window/等等。

假设你有一个 View 模型:

public class MainViewModel
{
public MainViewModel()
{
//Create some fake data
InnerStaff = new ObservableCollection<StaffViewModel>();
InnerStaff.Add(new StaffViewModel {FirstName = "Sue", LastName = "Bucknell"});
InnerStaff.Add(new StaffViewModel {FirstName = "James", LastName = "Bucknell"});
InnerStaff.Add(new StaffViewModel {FirstName = "John", LastName = "Harrod"});

CvsStaff = new CollectionViewSource();
CvsStaff.Source = this.InnerStaff;
CvsStaff.Filter += ApplyFilter;
}

private string filter;

public string Filter
{
get { return this.filter; }
set
{
this.filter = value;
OnFilterChanged();
}
}

private void OnFilterChanged()
{
CvsStaff.View.Refresh();
}

internal ObservableCollection<StaffViewModel> InnerStaff { get; set; }
internal CollectionViewSource CvsStaff { get; set; }
public ICollectionView AllStaff
{
get { return CvsStaff.View; }
}

void ApplyFilter(object sender, FilterEventArgs e)
{
StaffViewModel svm = (StaffViewModel)e.Item;

if (string.IsNullOrWhiteSpace(this.Filter) || this.Filter.Length == 0)
{
e.Accepted = true;
}
else
{
e.Accepted = svm.LastName.Contains(Filter);
}
}
}

假设您有一个窗口 MainWindow.cs(代码隐藏),您可以(对于本示例)在此处连接 DataContext。

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}

然后您有几个选择来进行绑定(bind),您可以在 XAML 或代码中指定 CollectionViewSource,但您已经完成了这两种操作。即 xaml 一个,键 x:key="StaffGroup"和 VM 一个 CvsStaff。假设我们完全摆脱了 xaml 并使用了正确设置的 VM。然后您将使用 ItemsSource 属性进行绑定(bind),如下所示:

<ListView Name="staffList" 
AlternationCount="2"
ItemsSource="{Binding AllStaff}"
Grid.Row="1" />

还有一件小事,我更改了过滤器以检查空值和空格。您可能还需要将其更改为不区分大小写。

我在这里没有提到但很重要的另一件事是在您的 StaffViewModel 上实现 INotifyPropertyChanged - 我假设您有,如果没有,这里有一些代码。您通常还会在大多数 View 模型上执行此操作,以通知 View 属性更改。

internal class StaffViewModel : INotifyPropertyChanged
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}

private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
OnPropertyChanged("LastName");
}
}
public override string ToString()
{
return string.Format("{0} {1}", FirstName, LastName);
}

public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}

关于c# - 使用 Josh Smith 的 WPF MVVM 演示应用程序实现 ListView 筛选器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12188623/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com