如何创建WPF ListCollectionView以对DataGrid CollectionViewSources进行排序

时间:2011-12-14 22:45:22

标签: wpf c#-4.0 datagrid collectionviewsource listcollectionview

以下是我的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}}" />

我目前有以下控件互相提供数据:

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

<Grid DataContext="{StaticResource topLevelAssysViewSource}">

ComboBox:

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

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" />

最后,我试图使一个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>

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

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

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

但是,我一直收到错误消息Null Reference Exception Unhandled:“对象引用未设置为对象的实例。”

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

1 个答案:

答案 0 :(得分:0)

请提供异常的完整堆栈跟踪,或者示例中至少引发此异常的行数。

根据您目前提供的内容,我认为错误的来源是

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

如果您使用的是Entity Framework,则ObjectQuery Results的默认视图将不是ListCollectionView,因此为NullReferenceException。

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

例如,尝试这些方面:

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();

更改绑定以引用CollectionViewSource.View属性:

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

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