0

WPFで基本的なフィルター付きリストボックスを実装しようとしています。ユーザーが何かを入力すると、リストは入力されたフレーズで始まる値に絞り込まれます。

私は持っています:

  • ビュー: _
    • InstitutionFilteringStringデータコンテキストとして設定されているViewModelクラスのプロパティにTextプロパティがバインドされているTextBox 、
    • 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は正しく呼び出されます。ここからのアドバイスに従って、セッターはコレクションビューでRefresh()メソッドを呼び出します。FilterInstitutions()メソッドが呼び出されます。

そして今バグ:文字列が1秒の直前に設定されていても、FilterInstitutionsメソッド内ではnullです。デバッガーを呼び出しスタックの下に移動すると、セッターの観点からは、入力された値に設定されたままですが、フィルタリングメソッド内ではnullになります。

セッターには、コメントアウトされたコード行があります。コメントを外すとバグは修正されますが、どのように行うべきかはほとんどわかりません。

私は何が間違っているのですか?

(わかりませんが、セッターとフィルタリングメソッドがクラスの2つの異なるインスタンスで動作しているように見えます。しかし、どうすれば1つのインスタンスだけを作成し、クラスはクローン化できません)

編集

すみません、嘘をついたようです。コンストラクターにブレークポイントを設定しましたが、実際にクラスの2つのインスタンスを作成し、両方に対してCollectionViewSource.GetDefaultView同じインスタンスを返すようです。ICollectionViewでも、実際には同じコレクションに対して2つのビューが必要です。まあ、私はこの答えに従いました、そしてそれはうまくいくようです:)

4

1 に答える 1

0

あなたは一度あなたの機関を作りますか?を設定します

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

一度?はいの場合は大丈夫です:)これのコードとFilterInstitutionsメソッドのコードを投稿できますか?私は自分のプロジェクトでずっとそれをやっていて、問題はありません。

于 2012-05-03T06:22:56.697 に答える