如何在重新排序数据网格的列后获取新的列顺序?

时间:2011-07-12 14:10:06

标签: c# .net wpf silverlight datagrid

在数据网格中拖放一些列之后,如何以MVVM方式将新订单传递给Viewmodel?

EventArgs非常奇怪。

DataGrid_Reordered传递一个只包含一个列的DataGridColumnEventArgs。我该怎么办呢?我怎么知道列的新顺序?

显然,列的顺序由DisplayIndex确定,但我如何知道旧值是什么以及新值是什么以及它与整个列集的关系如何?

非常感谢,

2 个答案:

答案 0 :(得分:1)

在页面中,我为DataGrid设置了一个LoadedColumnDisplayedIndexChanged事件。两者兼有很重要,我将在底部进行解释。

<DataGrid x:Name="dataGrid"
              Loaded="dataGrid_Loaded" 
              ColumnDisplayIndexChanged="dataGrid_ColumnDisplayIndexChanged" 
              ItemsSource="{Binding modulecollection, 
                            Source={StaticResource viewmodel}}"/>

任何一个事件触发后,我都会将发送者发送到DataGrid。然后访问所有列对象的DataGrid.Columns

我将其发送给另一个函数,该函数从DataGridColumn类创建列名称的快速数组。数组的索引与其他地方引用的列的顺序保持同步。您可以创建所需的任何内容,键值对,另一个类,并利用所需的DataGridColumn类中的任何对象。只取决于它的设置。

        string [] displayedColumnOrder;

    private void dataGrid_ColumnDisplayIndexChanged( object sender , DataGridColumnEventArgs e )
    {
        DataGrid _dataGrid = ( DataGrid ) sender;
        _getColumnOrder( _dataGrid.Columns );        
    }

    private void dataGrid_Loaded( object sender , RoutedEventArgs e )
    {
        DataGrid _datagrid = ( DataGrid ) sender;  
        _getColumnOrder( _datagrid.Columns );
    }
    void _getColumnOrder( IEnumerable<DataGridColumn> columnCollection )
    {
        DataGridColumn [] columnArray;
        int columnIndexWorking;
        displayedColumnOrder = new string [columnCollection.Count() ];
        columnArray = columnCollection.ToArray();

        foreach( var item_Column in columnCollection )
        {
            columnIndexWorking = item_Column.DisplayIndex;
            displayedColumnOrder [ columnIndexWorking ] = item_Column.Header.ToString();         
        }                                                                                        
    }

好的,您需要来自Loaded的事件来获得基线。在这里,我的DataGrid是从绑定源加载的,因此除非列加载时捕获了列顺序,否则我将没有列顺序的基准。

您需要ColumnDisplayedIndexChanged,因为您想跟踪列顺序的变化。

我发现的一件重要事情是,当用户将列移动几行时,ColumnDisplayedIndexChanged会为它移动的每个索引触发。如下所示,由于移动了一列,因此事件将针对它移到的每个空间触发。 DataGridColumn的Header对象也为空。因此,如果您谨慎使用此方法,则可能需要添加一些其他处理方法。或利用它来跟踪对变更的响应。示例:除非headervalue不为null,否则不要在后台线程中重新计算内容。

原文:

A|B|C   <- Column Name
0|1|2   <- Column Index

用户更改为:

B|C|A
0|1|2

用户将一列移到上方,ColumnDisplayedIndexChanged事件将像这样触发:

第一个事件:

  null | B | C
  0    | 1 | 2

第二事件:

  B  | null | C
  0  |  1   | 2

第三事件:

  B | C | A
  0 | 1 | 2

答案 1 :(得分:0)

不错的问题:-)我猜你是在重新启动应用程序后持久保存列顺序。

我不太喜欢网格,所以我没有任何具体的建议但是听起来像你最终会在视图模型中找到一堆属性(或者一个新的视图模型) )对列及其顺序进行建模。

我想您必须关闭AutoGenerateColumns,在Xaml中定义所需的列,并对每列的Header和DisplayIndex属性使用双向绑定以绑定到VM中的适当值。

通过这种方式,您可以使用MVVM Light中的EventToCommand行为,将其绑定到网格的ColumnReordering事件以及viewmodel中的RelayCommand。由于VM负责保存列的顺序,因此当事件触发时,它将在那里保存。

HTH

相关问题