0

我正在尝试在 WPF 中实现一个基本的过滤列表框。用户键入一些内容,列表缩小到以键入的短语开头的值。

我有:

  • 一个视图
    • 一个 TextBox,其 Text 属性绑定到InstitutionFilteringStringViewModel 类中的属性,该属性设置为数据上下文,
    • 一个 ListBox,其 ItemSource 属性绑定到视图模型中的一个ICollectionView命名Institutions
  • 具有上述属性的ViewModel类。

代码(去掉了不相关的部分):

class ChooseInstitiutionAndPublisherPageViewModel : WizardPageViewModelBase
{
    private ICollectionView _institutions;
    public ICollectionView Institutions
    {
        get
        {
            return _institutions;
        }
        set
        {
            _institutions = value;
            NotifyPropertyChanged("Institutions");
        }
    }

    private string _institutionFilteringString;
    public string InstitutionFilteringString
    {
        get
        {
            return _institutionFilteringString;
        }
        set
        {
            _institutionFilteringString = value;
            NotifyPropertyChanged("InstitutionFilteringString");
            //WORKAROUND
            //Institutions.Filter = new Predicate<object>(FilterInstitutions);
            Institutions.Refresh();
        }
    }

    public ChooseInstitiutionAndPublisherPageViewModel(WizardViewModel parent)
        : base(parent)
    {
        Institutions = CollectionViewSource.GetDefaultView(CentralRepository.Instance.GetInstitutions());
        Institutions.Filter = new Predicate<object>(FilterInstitutions);
    }

    private bool FilterInstitutions(object obj)
    {
        //I may refer directly to the field or through the property, it doesn't change anything
        if (_institutionFilteringString == null || _institutionFilteringString.Length == 0)
            return true;

        //some more filtering, irrelevant
        //[cut]
    }
}

视图和绑定:

<TextBox Text="{Binding Path=InstitutionFilteringString, Mode=TwoWay}" Height="23" Margin="6,6,87,0" Name="institutionNameTextBox" VerticalAlignment="Top" TextChanged="institutionNameTextBox_TextChanged" />
<ListBox Margin="6,35" Name="institutionsListBox" ItemsSource="{Binding Path=Institutions}" IsSynchronizedWithCurrentItem="True" />

所以,说到点子上了。的设置器InstitutionFilteringString被正确调用。根据此处的建议,setter 调用集合视图上的 Refresh() 方法。该FilterInstitutions()方法被调用。

现在是错误:即使字符串是在一秒钟之前设置的,但在FilterInstitutions方法内部它是空的。如果我在调用堆栈中使用调试器,从设置器的角度来看,它仍然设置为类型化的值,但在过滤方法内部它是空的。

在 setter 中有一行注释掉的代码。取消注释它可以修复错误,但这几乎不是应该如何完成的。

我究竟做错了什么?

(我不确定,但在我看来,setter 和过滤方法似乎对类的两个不同实例进行操作。但怎么可能,我只创建一个实例,并且类不可克隆)

编辑

对不起,我好像撒谎了。我在构造函数中放置了一个断点,看来我确实创建了该类的两个实例并为两者CollectionViewSource.GetDefaultView返回相同的实例。ICollectionView好吧,但我实际上希望对同一个集合有两个视图。好吧,我已经遵循了这个答案,它似乎有效:)

4

1 回答 1

0

你创建你的机构一次吗?并设置

Institutions.Filter = new Predicate<object>(FilterInstitutions)

一次?如果是,它可以:) 你可以发布你的代码以及 FilterInstitutions 方法的代码吗?我在我的项目中一直这样做并且没有问题。

于 2012-05-03T06:22:56.697 回答