如何创建一个WPF ListCollectionView来对数据聚合视图源进行排序

时间:2022-02-09 14:05:12

This is my first WPF project so please bare with me.

这是我的第一个WPF项目,所以请跟我说实话。

Here are my CollectionViewSources:

这里是我CollectionViewSources:

<CollectionViewSource x:Key="topLevelAssysViewSource" d:DesignSource="{d:DesignInstance my:TopLevelAssy, CreateList=True}" />
<CollectionViewSource x:Key="topLevelAssysRefPartNumsViewSource" Source="{Binding  Path=RefPartNums, Source={StaticResource topLevelAssysViewSource}}" />
<CollectionViewSource x:Key="topLevelAssysRefPartNumsRefPartNumBomsViewSource" Source="{Binding Path=RefPartNumBoms, Source={StaticResource topLevelAssysRefPartNumsViewSource}}" />

I currently have the following controls feeding data to one another:

我目前有以下控件相互传送数据:

DataContext for my window is fed through a Grid housing all of my Controls:

我的窗口的DataContext通过网格提供我的所有控件:

<Grid DataContext="{StaticResource topLevelAssysViewSource}">

A ComboBox:

一个下拉列表框:

<ComboBox DisplayMemberPath="TopLevelAssyNum" Height="23" HorizontalAlignment="Left"   ItemsSource="{Binding}" Margin="12,12,0,0" Name="topLevelAssysComboBox" SelectedValuePath="TopLevelAssyID" VerticalAlignment="Top" Width="120" />

a ListBox:

一个列表框:

<ListBox DisplayMemberPath="RefPartNum1" Height="744" HorizontalAlignment="Left" ItemsSource="{Binding Source={StaticResource topLevelAssysRefPartNumsViewSource}}" Margin="12,41,0,0" Name="refPartNumsListBox" SelectedValuePath="RefPartNumID" VerticalAlignment="Top" Width="120" />

Finally, a DataGrid which I am trying to make Sort-able: (Just one Column for now):

最后,我正在尝试的一个DataGrid:(现在只有一列):

<DataGrid CanUserSortColumns="true"  AutoGenerateColumns="False" EnableRowVirtualization="True" HorizontalAlignment="Left" ItemsSource="{Binding Source={StaticResource topLevelAssysRefPartNumsRefPartNumBomsViewSource}}" Margin="6,6,0,1" Name="refPartNumBomsDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Width="707">
    <DataGrid.Columns >
        <DataGridTextColumn x:Name="cageCodeColumn" Binding="{Binding Path=CageCode}" Header="CageCode" Width="45"  />
        <DataGridTextColumn x:Name="partNumColumn" Binding="{Binding Path=PartNum}" Header="PartNum" Width="165" SortDirection="Ascending" />
    </DataGrid.Columns>
</DataGrid>

My Exact code thus far is:

到目前为止,我的确切代码是:

public partial class MainWindow : Window
{
    racr_dbEntities racr_dbEntities = new racr_dbEntities();

    public MainWindow()
    {
        InitializeComponent();
    }

    private System.Data.Objects.ObjectQuery<TopLevelAssy> GetTopLevelAssysQuery(racr_dbEntities racr_dbEntities)
    {
        // Auto generated code

        System.Data.Objects.ObjectQuery<racr_dbInterface.TopLevelAssy> topLevelAssysQuery = racr_dbEntities.TopLevelAssys;
        // Update the query to include RefPartNums data in TopLevelAssys. You can modify this code as needed.
        topLevelAssysQuery = topLevelAssysQuery.Include("RefPartNums");
        // Update the query to include RefPartNumBoms data in TopLevelAssys. You can modify this code as needed.
        topLevelAssysQuery = topLevelAssysQuery.Include("RefPartNums.RefPartNumBoms");
        // Returns an ObjectQuery.
        return topLevelAssysQuery;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // Load data into TopLevelAssys. You can modify this code as needed.
        CollectionViewSource topLevelAssysViewSource = ((CollectionViewSource)(this.FindResource("topLevelAssysViewSource")));
        ObjectQuery<racr_dbInterface.TopLevelAssy> topLevelAssysQuery = this.GetTopLevelAssysQuery(racr_dbEntities);
        topLevelAssysViewSource.Source = topLevelAssysQuery.Execute(MergeOption.AppendOnly);

         ListCollectionView topLevelAssyView = CollectionViewSource.GetDefaultView(CollectionViewSource.CollectionViewTypeProperty) as ListCollectionView;
        topLevelAssyView.SortDescriptions.Add(new SortDescription("PartNum", ListSortDirection.Descending));
    }

I have read and understand the importance of creating the ListCollectionViews in order to handle the sort properties included in the CollectionViewSource, which I got from blog Bea Stollnitz's blog.

我已经阅读并理解了创建ListCollectionViews的重要性,以便处理CollectionViewSource中包含的排序属性,这是我从Bea Stollnitz博客获得的。

However, I keep getting the error message Null Reference Exception Unhandled: "Object reference not set to an instance of the object."

但是,我一直得到错误消息空引用异常的处理:“对象引用没有设置为对象的实例。”

How do I take care of this issue? Do I need to further define my ListCollectionView, or perhaps I need to establish an ICollectionView? My PartNum column contains part numbers that begin with numbers and sometimes letters. Will the standard sortdirections apply?

我如何处理这个问题?我需要进一步定义我的ListCollectionView吗,还是需要建立一个ICollectionView?我的PartNum列包含以数字开头的零件号,有时还有字母。是否适用标准的sortdirections ?

1 个解决方案

#1


0  

Please provide full stack trace for the exception, or at least number of line in your example which throws this exception.

请为异常提供完整的堆栈跟踪,或者在抛出该异常的示例中至少提供行数。

From what you've provided so far, I think that the source of error is

根据你到目前为止所提供的,我认为错误的来源是

ListCollectionView topLevelAssyView = CollectionViewSource.GetDefaultView(CollectionViewSource.CollectionViewTypeProperty) as ListCollectionView;

If you are using Entity Framework, the default View for ObjectQuery Results will not be ListCollectionView, hence NullReferenceException.

如果使用实体框架,ObjectQuery结果的默认视图将不是ListCollectionView,因此为NullReferenceException。

To use ObjectQuery/EntityCollection as the source for CollectionViewSource and sort with it you have to wrap it in some other container that supports sorting (and if want to perform CRUD, use that container everywhere instead of source EntityCollection).

要使用ObjectQuery/EntityCollection作为CollectionViewSource的源并对其进行排序,您必须将其打包到支持排序的其他容器中(如果想执行CRUD,请在任何地方使用该容器,而不是源EntityCollection)。

For example, try something along those lines:

例如,尝试以下方法:

ObservableCollection<TopLevelAssy> observableCollection = new ObservableCollection(topLevelAssysQuery.Execute(MergeOption.AppendOnly));
((ISupportInitialize)topLevelAssysViewSource).BeginInit();
topLevelAssysViewSource.CollectionViewType = typeof(ListCollectionView);
topLevelAssysViewSource.Source = observableCollection;
topLevelAssysViewSource.SortDescriptions.Add(new SortDescription("CageCode", ListSortDirection.Ascending));
((ISupportInitialize)topLevelAssysViewSource).EndInit();

And change your binding to refer to CollectionViewSource.View property:

并更改绑定以引用CollectionViewSource。视图属性:

ItemsSource="{Binding Source={StaticResource topLevelAssysViewSource}, Path=View}"

Additional reading: http://blog.nicktown.info/2008/12/10/using-a-collectionviewsource-to-display-a-sorted-entitycollection.aspx

更多阅读:http://blog.nicktown.info/2008/12/10/using-a-collectionviewsource-to-display-a-sorted-entitycollection.aspx

#1


0  

Please provide full stack trace for the exception, or at least number of line in your example which throws this exception.

请为异常提供完整的堆栈跟踪,或者在抛出该异常的示例中至少提供行数。

From what you've provided so far, I think that the source of error is

根据你到目前为止所提供的,我认为错误的来源是

ListCollectionView topLevelAssyView = CollectionViewSource.GetDefaultView(CollectionViewSource.CollectionViewTypeProperty) as ListCollectionView;

If you are using Entity Framework, the default View for ObjectQuery Results will not be ListCollectionView, hence NullReferenceException.

如果使用实体框架,ObjectQuery结果的默认视图将不是ListCollectionView,因此为NullReferenceException。

To use ObjectQuery/EntityCollection as the source for CollectionViewSource and sort with it you have to wrap it in some other container that supports sorting (and if want to perform CRUD, use that container everywhere instead of source EntityCollection).

要使用ObjectQuery/EntityCollection作为CollectionViewSource的源并对其进行排序,您必须将其打包到支持排序的其他容器中(如果想执行CRUD,请在任何地方使用该容器,而不是源EntityCollection)。

For example, try something along those lines:

例如,尝试以下方法:

ObservableCollection<TopLevelAssy> observableCollection = new ObservableCollection(topLevelAssysQuery.Execute(MergeOption.AppendOnly));
((ISupportInitialize)topLevelAssysViewSource).BeginInit();
topLevelAssysViewSource.CollectionViewType = typeof(ListCollectionView);
topLevelAssysViewSource.Source = observableCollection;
topLevelAssysViewSource.SortDescriptions.Add(new SortDescription("CageCode", ListSortDirection.Ascending));
((ISupportInitialize)topLevelAssysViewSource).EndInit();

And change your binding to refer to CollectionViewSource.View property:

并更改绑定以引用CollectionViewSource。视图属性:

ItemsSource="{Binding Source={StaticResource topLevelAssysViewSource}, Path=View}"

Additional reading: http://blog.nicktown.info/2008/12/10/using-a-collectionviewsource-to-display-a-sorted-entitycollection.aspx

更多阅读:http://blog.nicktown.info/2008/12/10/using-a-collectionviewsource-to-display-a-sorted-entitycollection.aspx