Multiple Views of Observable Collection with Datagrid

筅森魡賤 提交于 2019-12-13 00:42:34

问题


I have the same problem like this. But I´m using a DataGrid instead of a ListBox and it does not seem to work like this (it might also be because i never used visual basic and didnt translate the code correcly into c#). I basicly want two DataGrids on the same data with different filters.

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

The FilterContent method is being called without problems, but the DataGrid shows the lines anyway. If I use GetDefaultView the Filter works on both Datagrids. Do I have to use some other view instead of CollectionView (ListCollectionView does also not work)?

i have made a small sample project to show the problem sample. It only consists of an constructor and an observable collection.


回答1:


I got it to work somehow. I used CollectionViewSources now instead of 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>

and the c Code:

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

But I´m not sure why it works this way and the filter is not applied on window repaints when ICollectionView is used.




回答2:


You need to specify which ICollectionVIew is used on which DataGrid.

If you just bind to the collection (dataLines in this case) WPF will use the 'default view' (or create one if necessary), this is why the first commented out line works for filtering.

There are a few ways you could specify which view is used for which datagrid, depending on what patterns, etc. you are using

1) Like the linked question, you could set the ItemsSource for each DataGrid in the window's code behind, after initializing the views, e.g.:

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

2) You could set the DataContext of the window to itself, or make a view model for the screen that contains the view, and make the views public properties and then bind to the intended view for each grid, e.g.

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

Edit:

Now I'm not at work and can get to dropbox and play with your example it seems like the cause of the weird behaviour is the use of CollectionView directly. On the msdn page for CollectionView it says

You should not create objects of this class in your code. To create a collection view for a collection that only implements IEnumerable, create a CollectionViewSource object, add your collection to the Source property, and get the collection view from the View property.

However, if you don't want to set up the views in XAML, you could also change your CollectionViews to ListCollectionViews and it should work as expected (this is likely the view type that CollectionViewSource is making for you behind the scenes anyway).



来源:https://stackoverflow.com/questions/11786278/multiple-views-of-observable-collection-with-datagrid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!