使用Datagrid的Observable Collection的多个视图

时间:2012-08-02 21:46:11

标签: c# wpf datagrid filter observablecollection

我遇到像this这样的问题。但是我使用的是DataGrid而不是ListBox,它似乎不像这样工作(也可能是因为我从未使用过visual basic而且没有将代码正确地转换为c#)。 我基本上希望在具有不同过滤器的相同数据上使用两个DataGrids。

    ICollectionView view_dataLinesUnfiltered;
    ICollectionView view_dataLinesFiltered;

 public MainWindow()
    {
        ...
        //view_dataLines = CollectionViewSource.GetDefaultView(dataLines); // <- Filter works on both
        view_dataLinesUnfiltered = new CollectionView(dataLines); // <- Filter doesn´t work at all
        view_dataLinesFiltered = new CollectionView(dataLines);
        ....
        // Control Events
        this.ShowAA.RaiseEvent(new RoutedEventArgs(System.Windows.Controls.Primitives.ToggleButton.UncheckedEvent));

    }

    private void ShowAA_Checked(object sender, RoutedEventArgs e)
    {
        view_dataLinesUnfiltered.Filter = null;
    }

    private void ShowAA_UnChecked(object sender, RoutedEventArgs e)
    {
        view_dataLinesUnfiltered.Filter = delegate(object o) { return FilterContent(o as ErrorDetection.stDataLine, "AA", ""); };
    }

    bool FilterContent(ErrorDetection.stDataLine line, string sFilterAA, string sFilter)
    {
        shortArrayToHexStringConverter converter = new shortArrayToHexStringConverter();

        string comBuffer = converter.Convert(line.ComBufferP as object,typeof(string),0,System.Globalization.CultureInfo.CurrentCulture) as string;

        return false;// !comBuffer.Contains("AA");
    }

正在调用FilterContent方法没有问题,但DataGrid仍然显示行。如果我使用GetDefaultView,则Filter适用于两个Datagrids。我是否必须使用其他视图而不是CollectionView(ListCollectionView也不起作用)?

我做了一个小样本项目来展示问题sample。它只包含一个构造函数和一个可观察的集合。

2 个答案:

答案 0 :(得分:0)

您需要指定在哪个DataGrid上使用哪个ICollectionVIew。

如果你只是绑定到集合(在这种情况下是dataLines),WPF将使用&#39;默认视图&#39; (或者在必要时创建一个),这就是第一个注释掉的行用于过滤的原因。

有几种方法可以指定哪个视图用于哪个数据网格,具体取决于您使用的模式等

1)与链接的问题一样,您可以在初始化视图后为窗口代码中的每个DataGrid设置ItemsSource,例如:

filteredDataGrid.ItemsSource = view_dataLinesFiltered;
unfilteredDataGrid.ItemsSource = view_dataLinesUnfiltered;

2)您可以将窗口的DataContext设置为自身,或者为包含视图的屏幕创建视图模型,并使视图成为公共属性,然后绑定到每个网格的预期视图,例如

<DataGrid ItemsSource="{Binding View_dataLinesFiltered}"> ....

编辑:

现在我没有工作,可以使用Dropbox并玩你的例子,似乎奇怪的行为的原因是直接使用CollectionView。在msdn page for CollectionView上说

  

您不应在代码中创建此类的对象。创建一个   仅实现IEnumerable的集合的集合视图,   创建一个CollectionViewSource对象,将您的集合添加到   Source属性,并从View属性中获取集合视图。

但是,如果您不想在XAML中设置视图,您也可以将CollectionView更改为ListCollectionViews,它应该按预期工作(这可能是CollectionViewSource正在制作的视图类型无论如何,对你来说。)

答案 1 :(得分:0)

我以某种方式工作了。我现在使用CollectionViewSources而不是ICollectionView。

 <Window.Resources>
    <CollectionViewSource x:Key="viewSource_dataLinesUnfiltered"/>
    <CollectionViewSource x:Key="viewSource_dataLinesFiltered"/>
 </Window.Resources>
 ...
 <DataGrid Name="Filtered_Datagrid" ItemsSource="{Binding Source={StaticResource viewSource_dataLinesFiltered}}" >
  ...
 </DataGrid>
  ...
 <DataGrid Name="Unfiltered_Datagrid" ItemsSource="{Binding Source={StaticResource viewSource_dataLinesUnfiltered}}">
  ...
 </DataGrid>

和c代码:

    CollectionViewSource viewSource_dataLinesUnfiltered;
    CollectionViewSource viewSource_dataLinesFiltered;
    ...
    public MainWindow()
    {
        InitializeComponent();

        this.DataContext = dataLines;

        viewSource_dataLinesUnfiltered = (CollectionViewSource)this.Resources["viewSource_dataLinesUnfiltered"];
        viewSource_dataLinesUnfiltered.Source = dataLines;
        viewSource_dataLinesFiltered = (CollectionViewSource)this.Resources["viewSource_dataLinesFiltered"];
        viewSource_dataLinesFiltered.Source = dataLines;


        // Control Events
        this.ShowAA.RaiseEvent(new RoutedEventArgs(System.Windows.Controls.Primitives.ToggleButton.UncheckedEvent));

    }

    private void ShowAA_Checked(object sender, RoutedEventArgs e)
    {
        viewSource_dataLinesUnfiltered.View.Filter = null;
    }

    private void ShowAA_UnChecked(object sender, RoutedEventArgs e)
    {
        viewSource_dataLinesUnfiltered.View.Filter = delegate(object o) { return FilterContent(o as ErrorDetection.stDataLine, "AA", ""); };
    }

    bool FilterContent(ErrorDetection.stDataLine line, string sFilterAA, string sFilter)
    {
        shortArrayToHexStringConverter converter = new shortArrayToHexStringConverter();

        string comBuffer = converter.Convert(line.ComBufferP as object,typeof(string),0,System.Globalization.CultureInfo.CurrentCulture) as string;

        return !comBuffer.Contains("AA");
    }

但我不确定为什么它会以这种方式工作,并且当使用ICollectionView时,过滤器不会应用于窗口重绘。