これでデータグリッドにオブジェクトのリストをロードします:
_dataGrid1.Items.Add(model);
_
model
はデータベースのデータになります。 Id(int)
、Name(string)
およびText(string)
があります。
私のデータグリッドでは、model
の名前のみを表示しています。テキストボックスに何かを入力したときに、データグリッドをフィルタリングするにはどうすればよいですか?
私はこのページにいた: http://msdn.Microsoft.com/en-us/library/vstudio/ff407126(v = vs.100).aspx からのコードが理解できないそこに私はそれを私の問題のためにどのように転置するべきか説明できません。
コレクションをフィルタリングする方法は複数あります
これがあなたのアイテムクラスであることを示唆しましょう
public class Model
{
public string Name
{
get;
set;
}
}
そしてあなたのコレクションは次のようになります
var ObColl = new ObservableCollection<Model>();
ObColl.Add(new Model() { Name = "John" });
ObColl.Add(new Model() { Name = "Karl" });
ObColl.Add(new Model() { Name = "Max" });
ObColl.Add(new Model() { Name = "Mary" });
public MainWindow()
{
InitializeComponent();
// Collection which will take your ObservableCollection
var _itemSourceList = new CollectionViewSource() { Source = ObColl };
// ICollectionView the View/UI part
ICollectionView Itemlist = _itemSourceList.View;
// your Filter
var yourCostumFilter= new Predicate<object>(item => ((Model)item).Name.Contains("Max"));
//now we add our Filter
Itemlist.Filter = yourCostumFilter;
dataGrid1.ItemsSource = Itemlist;
}
public MainWindow()
{
InitializeComponent();
// Collection which will take your Filter
var _itemSourceList = new CollectionViewSource() { Source = ObColl };
//now we add our Filter
_itemSourceList.Filter += new FilterEventHandler(yourFilter);
// ICollectionView the View/UI part
ICollectionView Itemlist = _itemSourceList.View;
dataGrid1.ItemsSource = Itemlist;
}
private void yourFilter(object sender, FilterEventArgs e)
{
var obj = e.Item as Model;
if (obj != null)
{
if (obj.Name.Contains("Max"))
e.Accepted = true;
else
e.Accepted = false;
}
}
複数の条件や複雑なフィルターが必要な場合は、Predicatにメソッドを追加できます
// your Filter
var yourComplexFilter= new Predicate<object>(ComplexFilter);
private bool ComplexFilter(object obj)
{
//your logic
}
これは、ICollectionViewのFilterプロパティを使用する簡単な実装です。 XAMLにこれが含まれているとします。
<TextBox x:Name="SearchTextBox" />
<Button x:Name="SearchButton"
Content="Search"
Click="SearchButton_OnClick"
Grid.Row="1" />
<DataGrid x:Name="MyDataGrid"
Grid.Row="2">
<DataGrid.Columns>
<DataGridTextColumn Header="Lorem ipsum column"
Binding="{Binding}" />
</DataGrid.Columns>
</DataGrid>
次に、コンストラクターでデータのデフォルトビューを取得し、コレクションのすべてのアイテムに対して実行されるフィルター述語を設定できます。 CollectionViewはいつコレクションを更新する必要があるかを認識しないため、ユーザーが検索ボタンをクリックしたときにRefreshを呼び出す必要があります。
private ICollectionView defaultView;
public MainWindow()
{
InitializeComponent();
string[] items = new string[]
{
"Asdf",
"qwer",
"sdfg",
"wert",
};
this.defaultView = CollectionViewSource.GetDefaultView(items);
this.defaultView.Filter =
w => ((string)w).Contains(SearchTextBox.Text);
MyDataGrid.ItemsSource = this.defaultView;
}
private void SearchButton_OnClick(object sender, RoutedEventArgs e)
{
this.defaultView.Refresh();
}
このURLで、CollectionViewsのより詳細な説明を見つけることができます。 http://wpftutorial.net/DataViews.html
@WiiMaxx、担当者が不足しているためコメントできません。そこでの直接キャストについてはもう少し注意が必要です。同じフィルターが別の複合型データを保持するグリッドに適用された場合、InvalidCastExceptionが発生する可能性があります。
// your Filter
var yourCostumFilter= new Predicate<object>(item =>
{
item = item as Model;
return item == null || item.Name.Contains("Max");
});
これはデータグリッドを壊すことはなく、キャストが失敗した場合に結果をフィルタリングしません。コードを間違えても、ユーザーへの影響は少なくなります。さらに、「as」演算子が直接キャスト操作のように明示的な型強制を行わないため、フィルターが高速になります。
データグリッド行をフィルタリングするために、dataviewフィルターを使用できます。
DataView dv = datatable.DefaultView;
StringBuilder sb = new StringBuilder();
foreach (DataColumn column in dv.Table.Columns)
{
sb.AppendFormat("[{0}] Like '%{1}%' OR ", column.ColumnName, "FilterString");
}
sb.Remove(sb.Length - 3, 3);
dv.RowFilter = sb.ToString();
dgvReports.ItemsSource = dv;
dgvReports.Items.Refresh();
「datatable」はデータグリッドに与えられたデータソースであり、文字列ビルダーを使用してフィルタークエリを作成します。「フィルター文字列」はデータグリッドで検索するテキストであり、それをdataviewに設定し、最後にデータビューをitemsourceとしてデータグリッドに設定します。更新してください。
dataBindingを見てください->あなたのケースではアイテムをグリッドに追加せず、itemssourceを設定してください
<Datagrid ItemsSource="{Binding MyCollectionOfModels}" />
または
dataGrid1.ItemsSource = this._myCollectionOfModels;
何らかのフィルタリング、並べ替え、グループ化が必要な場合は、 CollectionView を見てください。