CollectionViewSource,如何筛选数据? [英] CollectionViewSource, how to filter data?

查看:377
本文介绍了CollectionViewSource,如何筛选数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我绑定一个ComboBox实体,但我想要的数据进行过滤。

I am binding a ComboBox to Entities but I want the data filtered.

到现在为止我已经尝试了两种方式:

Up to now I have tried two ways:


  • 简单之一:直接涂于过滤器的对象集throught
    LINQ到实体

  • 设置过滤事件处理程序的描述上
    MSDN

  • "simple" one: Apply the filter directly to the ObjectSet throught LINQ to Entities
  • setting a filtering event handler as described on msdn

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

I am satisfied by the first approach, above all because the query generated to the database contains a WHERE clause, so not all the whole data have to be retrieved from the remote db....

然而,#2的方法是通过更为灵活,如果在运行时我想改变应用的过滤......我按照MSDN上的例子,但我得到一个异常,为什么?

However, the #2 approach is by far more flexible, if at runtime i'd like to change the filtering applied... I have followed the example on msdn, but I get an exception, why?

所以,我的问题是:结果
1.哪种方法比较好结果
2.为什么我得到的例外呢?

So, my questions are:
1. Which approach is better
2. Why I get the exception?

下面是我的code:

 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;
            }
        }
    }

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

EDIT: I have tried implementing the Filter property on the View rather than setting the EventHandler:

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

System.NotSupportedException: Specified method is not supported. at System.Windows.Data.CollectionView.set_Filter(Predicate`1 value)

修改

XAML code:

XAML code:

<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绑定,而不是在背后code ...

推荐答案

铝最后我找到了一个解决方案,因为还发布<一个href=\"http://stackoverflow.com/questions/2702434/entity-framework-4-0-databinding-with-sorting-not-working/2720540#2720540\">in这个问题
到expliticy申报集合类型:

Al last I have found a solution, as posted also in this question to expliticy declare the type of the Collection:

Col​​lectionViewType =的ListCollectionView

因此​​,在XAML添加的集合类型:

So in XAML added the Collection type:

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

和在code现在事件处理程序如下:

And in code now the Event Handler works:

myCollectionViewSource.Filter += new FilterEventHandler(filterSource);

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

The only regret is that I did not understand why, for something apparently so simple, I have to force it "by hand" in XAML ??? To me this seems like an hack, and also very error prone...

这篇关于CollectionViewSource,如何筛选数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆