2013-01-24 70 views
4

我将一个ComboBox绑定到实体,但我想过滤数据。CollectionViewSource,如何过​​滤数据?

到现在我都试过两种方式:

  • “简单的”一:直接应用过滤器的对象集throught LINQ到实体
  • 设置过滤事件处理程序上 msdn
  • 描述

我很满意第一的方针,首先是因为生成的数据库查询包含一个WHERE子句,所以不是所有的整个数据必须从远程检索db ....

然而,#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; 
      } 
     } 
    } 

编辑:我曾尝试推行视图上的过滤器属性,而不是设置事件处理程序:

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值)

编辑

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绑定,不在代码后面...

回答

5

铝最后我已经发现一个解决方案,因为还贴in this question 到expliticy声明集的类型:

CollectionViewType = “的ListCollectionView”

因此在XAML中添加了Collection类型:

<CollectionViewSource x:Key="tSCHEDEViewSource" d:DesignSource="{d:DesignInstance my:TSCHEDE, CreateList=True}" CollectionViewType="ListCollectionView"> 
    </CollectionViewSource> 

而在代码现在事件处理程序的工作原理:

myCollectionViewSource.Filter += new FilterEventHandler(filterSource); 

唯一遗憾的是,我不明白为什么,什么东西显然是如此简单,我有“手”在给力了XAML? 对我来说这似乎是一个黑客,也很容易出错...

+4

难道你只是恨,当有人没有留下评论的选票? –

+0

也许他们收到了这个错误 - 'CollectionViewType属性只能在初始化过程中设置.' – TaterJuice

+0

@ Warlord099这很奇怪。我们从不抱怨upvotes ...只是一个想法。但是,是的,我们几乎可以肯定它已经完成了,因为评论/帖子帮助了这个人。 – Yatin

6

检查此

1)CollectionView Filtering

滤波需要基于委托(谓词),其上会发生过滤器。 Predicate根据它返回的值true或false接受项目an,它选择或取消选择一个元素。

this.Source.Filter = item => { 
    ViewItem vitem = item as ViewItem; 
    return vItem != null && vitem.Name.Contains("A"); 
}; 

2)FIltering the data Dynamically

+0

我跟着你第一个链接,但后一点的事情变得有点太复杂了...... 首先,我从得到myCollectionViewSource.View是一个ICollectionView,它似乎不支持排序筛选(属性CanSort,CanFilter为false) 在XAML中我有: spiderman77

+3

出生的程序员做复杂的事情:-) –

+1

事实上,这是答案。 –