WPF Toolkit DataGrid 列调整大小事件

Posted

技术标签:

【中文标题】WPF Toolkit DataGrid 列调整大小事件【英文标题】:WPF Toolkit DataGrid column resize event 【发布时间】:2011-04-30 07:23:51 【问题描述】:

我在我正在开发的一个应用程序中使用 WPF Toolkit Datagrid。我想要的是将列宽和显示索引存储为用户首选项。我已经为列显示索引实现了它,但对于调整大小,我在数据网格上找不到任何将在列大小更改后触发的事件。 我已经尝试过“SizeChanged”事件,我猜它仅在最初计算大小时才会触发,而且它也适用于整个数据网格,而不适用于各个列。 任何替代解决方案或是否有人知道该事件?

【问题讨论】:

【参考方案1】:

取自...:

http://forums.silverlight.net/post/602788.aspx

加载后:

    PropertyDescriptor pd = DependencyPropertyDescriptor
                             .FromProperty(DataGridColumn.ActualWidthProperty,
                                           typeof(DataGridColumn));

        foreach (DataGridColumn column in Columns) 
                //Add a listener for this column's width
                pd.AddValueChanged(column, 
                                   new EventHandler(ColumnWidthPropertyChanged));
        

2 种方法:

    private bool _columnWidthChanging;
    private bool _handlerAdded;
    private void ColumnWidthPropertyChanged(object sender, EventArgs e)
    
        // listen for when the mouse is released
        _columnWidthChanging = true;
        if (!_handlerAdded && sender != null)
        
            _handlerAdded = true;  /* only add this once */
            Mouse.AddPreviewMouseUpHandler(this, BaseDataGrid_MouseLeftButtonUp);
        
    

    void BaseDataGrid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    
        if (_columnWidthChanging) 
            _columnWidthChanging = false;
          // save settings, etc

        

        if(_handlerAdded)  /* remove the handler we added earlier */
        
             _handlerAdded = false;
             Mouse.RemovePreviewMouseUpHandler(this, BaseDataGrid_MouseLeftButtonUp);
        
    

当用户拖动宽度时,ColumnWidthPropertyChanged 会不断触发。添加 PreviewMouseUp 处理程序可让您在用户完成时进行处理。

【讨论】:

如果我们使用双击它不起作用。双击设置“自动”列宽。 @Rover ...但是双击有一个容易捕捉的事件。我不明白问题出在哪里。 一个问题是你添加了很多事件处理程序 那么如何获取新的列宽呢? 这会导致内存泄漏地狱。此外,Mouse up 事件将触发数千次。【参考方案2】:

布局更新了吗?

我在 Silverlight 中工作,并且网格每秒都会反弹/刷新。

我正在使用 LayoutUpdated 方法,该方法会针对每个布局更新事件触发。

您可以保留列宽字典并检查增量。然后你就会知道哪些列发生了变化。

foreach (DataGridColumn column in dataGrid1.Columns)

    // check for changes...
    // save the column.Width property to a dictionary...

【讨论】:

【参考方案3】:

我假设您希望保存列宽,以便下次启动应用程序时使用相同的列宽来生成数据网格。

如果是这种情况,那么另一种方法是在应用程序关闭时保存列宽(和索引),这也比每次调整列大小时保存宽度更有效。

根据您的应用程序的结构,这样的事情应该可以工作......

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)

  foreach (DataGridColumn column in dataGrid1.Columns)
  
    // save the column.Width property to a user setting/file/registry/etc...
    // optionally save the displayindex as well...
  
 

【讨论】:

嗨,你能给我一些关于如何将值从 c# 复制到 xaml 的线索吗?我试过这个: Dictionary list = new Dictionary(); foreach (DataGridView.Columns 中的 DataGridColumn 列) DataGridLength x = column.Width; list.Add(column.Header.ToString(), x); 【参考方案4】:

您可以尝试扩展DataGrid,然后实现NotifyPropertyChange 事件。像这样的:

class MyDataGrid : DataGrid, INotifyPropertyChanged

    private DataGridLength _columnWidth;
    public DataGridLength ColumnWidth
    
        get  return _columnWidth; 
        set
        
            _columnWidth = value;
            NotifyPropertyChanged("ColumnWidth");
        
    

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        
            handler(this, new PropertyChangedEventArgs(propertyName));
        
    

从那里,您可以向处理程序添加一个 delagate 来执行您希望它执行的任何操作。比如:

MyDataGrid dataGrid;
//init grid, do stuff

dataGrid.PropertyChanged += new PropertyChangedEventHandler(ColumnWidthChanged);
//ColumnWidthChanged will be a method you define

现在你有了 delagate,你可以定义当列宽改变时你想要发生的事情:

private void ColumnWidthChanged(object sender, PropertyChangedEventArgs args)

    if(args.PropertyName.Equals("ColumnWidth"))
    
        //Do stuff now that the width is changed
    

您会注意到我正在检查哪个属性已更改。我设置它的方式是,您可以扩展其他属性并为它们的更改创建处理程序。如果您想要多个处理程序,最好创建一个DataGridPropertyChanged 方法来切换更改了哪个属性。然后它将为每个被更改的属性调用适当的方法(例如ColumnWidthChanged)。这样,您就不必检查每个处理程序是否只修改一个属性。

您没有指定语言,因此我将其重新标记为 C#。但是,如果您使用的是 VB,它应该足够简单。

希望这会有所帮助!

【讨论】:

这并没有真正的帮助,因为您只有一个列宽,并且只有在代码中调整列大小时才会引发您的事件,无论如何您都可以捕获。

以上是关于WPF Toolkit DataGrid 列调整大小事件的主要内容,如果未能解决你的问题,请参考以下文章

WPF MvvM DataGrid 动态列

wpf datagrid过滤器列标题值访问

.NET 4 WPF Datagrid 和 WPF Toolkit Datagrid 之间的差异

WPF Toolkit Datagrid - 如何关闭选择?

WPF Toolkit Datagrid - 如何关闭选择?

WPF DataGrid 同步列宽