ComboBoxをエンティティにバインドしていますが、データをフィルタリングしたいと思います。
これまで、私は2つの方法を試しました。
- 「単純な」もの:LINQtoEntitiesを介してObjectSetに直接フィルターを適用します
- msdnで説明されているようにフィルタリングイベントハンドラーを設定する
データベースに対して生成されたクエリにWHERE句が含まれているため、最初のアプローチに満足しています。したがって、すべてのデータをリモートデータベースから取得する必要はありません。
ただし、実行時に適用されるフィルタリングを変更したい場合は、#2のアプローチの方がはるかに柔軟です... msdnの例に従いましたが、例外が発生します。なぜですか?
したがって、私の質問は次のとおり
です。1.どちらのアプローチが優れている
か2.なぜ例外が発生するのですか?
これが私のコードです:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
//Do not load your data at design time.
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
//Load your data here and assign the result to the CollectionViewSource.
System.Windows.Data.CollectionViewSource myCollectionViewSource =
(System.Windows.Data.CollectionViewSource)
this.Resources["tSCHEDEViewSource"];
// If I use this I get the data filtered on startup, but is it the right mode?
//myCollectionViewSource.Source = _context.TSCHEDE.Where(s => s.KLINEA == kLinea && s.FCANC == "T").OrderBy(s => s.DSCHEDA).OrderByDescending(s => s.DSTORICO);
// Instead If I apply my custom filtering logic
myCollectionViewSource.Filter += new FilterEventHandler(filterSource);
myCollectionViewSource.Source = _context.TSCHEDE; // ... Here i get an exception:
// 'System.Windows.Data.BindingListCollectionView' view does not support filtering. ???
}
}
private void filterSource(object sender, FilterEventArgs e)
{
TSCHEDE scheda = e.Item as TSCHEDE;
if (scheda != null)
{
if (scheda.KLINEA == 990)
{
e.Accepted = true;
}
else
{
e.Accepted = false;
}
}
}
編集:EventHandlerを設定するのではなく、ビューにFilterプロパティを実装しようとしました:
myCollectionView = (BindingListCollectionView)myCollectionViewSource.View;
myCollectionView.Filter = new Predicate<object>(Contains);
public bool Contains(object de)
{
TSCHEDE scheda = de as TSCHEDE;
return (scheda.KLINEA == 990);
}
そして今、私はそれほど有用ではない例外を受け取ります:
System.NotSupportedException:指定されたメソッドはサポートされていません。System.Windows.Data.CollectionView.set_Filter(Predicate`1 value)で
編集
XAMLコード:
<UserControl.Resources>
<CollectionViewSource x:Key="tSCHEDEViewSource" d:DesignSource="{d:DesignInstance my:TSCHEDE, CreateList=True}" >
</CollectionViewSource>
<DataTemplate x:Key="SchedaTemplate">
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Path=KSCHEDA}" Width="60"></TextBlock>
<TextBlock Text="{Binding Path=DArticolo}" Width="200"></TextBlock>
<TextBlock Text=" - " Width="40"></TextBlock>
<TextBlock Text="{Binding Path=DSTORICO}" Width="150"></TextBlock>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid Background="PapayaWhip" DataContext="{StaticResource tSCHEDEViewSource}" DataContextChanged="StartHere" Name="rootGrid">
<ComboBox ItemTemplate="{StaticResource SchedaTemplate}" Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" ItemsSource="{Binding}" Margin="23,129,0,0" Name="tSCHEDEComboBox1" SelectedValuePath="KSCHEDA" VerticalAlignment="Top" Width="393">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
</Grid>
今、私は問題がコードビハインドではなく、XAMLバインディングにあると考えています...