0

と がObservableCollectionバインドComboBoxされています。私が達成したいのは、それをフィルタリングし、フィルタリングされたアイテムObservableCollectionのみを表示させることです。ComboBox後でどこかにforeach (item in ComboBox) loop. フィルタリングは、いくつかの文字を書くことによって行われるべきであり、そのアイテムの name プロパティにObservableCollectionその文字が含まれていない場合は、そのアイテムを削除します。

プロパティを使用して ComboBox に直接入力する方法があることは知っていIsEditableますが、この例では、ユーザーの入力に追加の TextBox を使用します。

練習のために、私は(より多くのプロパティを持つObservableCollection<string>my ではなく)でそれをやっています。<myClass>

public MainWindow()
    {

        InitializeComponent();

        names= new ObservableCollection<string>();

        names.Add("Harry");
        names.Add("Ron");
        names.Add("Einstein");
        names.Add("Frodo");
        names.Add("Spiderman");

        myComboBox.DataContext = this;
    }

         public ObservableCollection<string> names{ get; set; }
         public ObservableCollection<string> filteredNames{ get; set; }

私はこのメソッドを作成しました:

 void toFilter()
      {
      filteredNames=new ObservableCollection<string>(names.Where(name=> name.StartsWith(myTextBox.Text)));
      }      

そしてでtext changed

private void myTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (myTextBox.Text.Length > 0)
            {
                toFilter();
            }
            myComboBox.DataContext = this; //Obviously doesn't work
        }

そのため、元のコレクションをそのまま保持し ( names)、filteredNamesテキスト ボックスに何かが入力されたときに表示したいと考えています。コンボボックスをfilteredNames(最初は に等しいnames) に直接バインドし、毎回テキスト ボックスの入力と一致しない名前をループして削除する必要がありますmyTextBox_TextChangedか?

他のアプローチは、何かが からnamesに入力されたときに、コンボ ボックスのバインドを変更することfilteredNamesです。

これはどのように簡単に達成できますか?

編集:

CollectionViewSource の使用を提案していただきありがとうございます。この例では完全に機能しましたが、実際のプログラムではいくつかの問題が発生しています。問題のある部分をこれに減らしました(XAML Loverソリューションから)

view.Filter = delegate(object o)
                        {

                            if (o.ToString().StartsWith(myTextBox.Text))
                            {
                                return true;
                            }
                            return false;

                        };

次の動作を見てきました。何も書き込まない場合、ファイルがロードされると、コンボボックスにデータが入力され、すべて問題ありません。「Unico.Canal」と違うものを書くと、すべてのデータがコンボボックスから消えてしまいます (Unico は私の名前空間で、Canal は CollectionViewSource のクラスです)。そこにファイル読み取りメソッドがあるため、コードは少し混乱しています (そして非常に長い)。コードを適切な場所に配置していないと思います。その「デリゲート」が正確に何をしているのか、そしてそれがどのように機能するのかを誰かが説明してもらえますか?

4

4 に答える 4

1

CollectionViewSource を使用し、そのソースを名前コレクションに設定します。

viewModel では、次のように collectionViewSource を設定します。

CollectionViewSource myCollectionViewSource = new CollectionViewSource();
myCollectionViewSource.Source = names;

collectionViewSource 内の項目をフィルタリングする述語を設定する必要があります


myCollectionViewSource.View.Filter = new Predicate(this.MyFilter);
public bool MyFilter(string item)
{
  // put whatever filtering logic you have in here
  return item.StartsWith(myTextBox.Text);
}

次に、collectionViewSource をプロパティとしてビューに公開します。


public CollectionViewSource MyCollectionViewSource 
{
  get
  {
    return myCollectionViewSource;
  }
  set
  {
    myCollectionViewSource = value;
    // make sure to raise INotifyPropertyChanged here
  }
}

XAML では、ComboBox は次のようになります。

<ComboBox ItemsSource="{Binding MyCollectionViewSource.View}" />
于 2013-05-29T08:57:37.767 に答える
0

あなたの問題を正しく理解していれば、これを変更します

public ObservableCollection<string> FilteredNames{ get; set; }

public ObservableCollection<string> FilteredNames
{ 
    get
       {
            if(IsNamesFilterd)
            {
                return _filteredNames;
            }
            else
            {
                return _names ;
            }
       }
 }

イベント ハンドラ コードのブール条件を変更します。ブール値を変更した後も NotifyPropertyChanged 。

于 2013-05-29T08:43:17.520 に答える
0

ICollectionViewの代わりに、データ バインドされたプロパティ タイプとして使用しObservableCollection<string>ます。

namesView = CollectionViewSource.GetDefaultView(names);
namesView.Filter = item =>
{
    if (myTextBox.Text.Length > 0)
    {
        return ((string)item).StartsWith(myTextBox.Text);
    }
    return true;
};

private void myTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    namesView.Refresh();
}
于 2013-05-29T08:45:59.223 に答える