【问题标题】:How to create a WPF ListCollectionView to sort DataGrid CollectionViewSources如何创建 WPF ListCollectionView 对 DataGrid CollectionViewSources 进行排序
【发布时间】:2011-12-14 22:45:22
【问题描述】:

这是我的 CollectionViewSource:

<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 DisplayMemberPath="TopLevelAssyNum" Height="23" HorizontalAlignment="Left"   ItemsSource="{Binding}" Margin="12,12,0,0" Name="topLevelAssysComboBox" SelectedValuePath="TopLevelAssyID" VerticalAlignment="Top" Width="120" />

一个列表框:

<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: “Object reference not set to an instance of the object.”

我该如何处理这个问题?我是否需要进一步定义我的 ListCollectionView,或者我需要建立一个 ICollectionView?我的 PartNum 列包含以数字和字母开头的零件编号。标准排序方向是否适用?

【问题讨论】:

    标签: wpf c#-4.0 datagrid collectionviewsource listcollectionview


    【解决方案1】:

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

    从你目前提供的情况来看,我认为错误的来源是

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

    如果您使用实体框架,ObjectQuery 结果的默认视图将不是 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

    【讨论】:

    • 感谢您的回复,Surfen -- 我真的很感激。您是正确的,因为错误消息确实落在定义 ListCollectionView 的行上。正如您所说,我确实尝试创建一个 ObservableCollection 并更改我的 ItemsSource,但这有点超出我的想象,我无法成功运行编辑后的代码。我将回顾您所说的内容,并尝试对我的问题进行更有洞察力的重新发布。
    • 不客气。顺便说一句,我不确定是否可以在通过 XAML 实例化后更改 CollectionViewType,因此您可能希望将此分配移至 XAML。但是我在 CollectionViewSources 方面遇到了一些其他问题,最终我最终在代码中创建和维护它们。
    • 嗯...仍然没有解决方案。我真的觉得我需要 1. 为我的 collectionViewSources 建立一个 observablesCollection,或者 2. 创建一个 ICollectionView。这看起来确实比实际实现起来更简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-11
    • 2010-12-24
    • 2011-08-12
    • 2010-12-10
    • 2017-06-09
    • 1970-01-01
    • 2011-02-13
    相关资源
    最近更新 更多