一、前言
在專案開發過程中,DataGrid是經常使用到的一個資料展示控制元件,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支援固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬的兩個DataGrid合併在一起的方式,原部落格:https://www.cnblogs.com/akwkevin/p/17872348.html)
二、正文
1、上面大佬的實現,就直接基於他自己的控制元件庫裡實現的,這裡我介紹的方式是如何引用了別的第三方庫的情況下,在專案程式碼中再實現自定義可以固定右側列的DataGrid控制元件;
2、首先新建個專案,專案裡引用了HandyControl控制元件庫和微軟的mvvm庫。
3、給專案新增一個自定義控制元件,記得不是自定義使用者控制元件,這裡命名為MyDataGrid,然後就可以從上面大佬那裡搬程式碼過來,關鍵就是新增RightFrozenCount這個依賴屬性程式碼和兩個DataGrid之間的滾動同步程式碼
public int RightFrozenCount { get { return (int)GetValue(RightFrozenCountProperty); } set { SetValue(RightFrozenCountProperty, value); } } public static readonly DependencyProperty RightFrozenCountProperty = DependencyProperty.Register(nameof(RightFrozenCount), typeof(int), typeof(MyDataGrid), new PropertyMetadata(0, OnRightFrozenCountChanged)); private static void OnRightFrozenCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is MyDataGrid dataGridRightFrozen) { dataGridRightFrozen.OnRightFrozenCountChanged(); } } private void OnRightFrozenCountChanged() { if (_rightDataGrid != null) { if (RightFrozenCount > 0) { for (int i = 0; i < _rightDataGrid.Columns.Count; i++) { var column = _rightDataGrid.Columns[i]; _rightDataGrid.Columns.Remove(column); Columns.Add(column); } for (int i = 0; i < RightFrozenCount; i++) { var last = Columns[^1]; Columns.Remove(last); _rightDataGrid.Columns.Insert(0, last); } _rightDataGrid.SetCurrentValue(VisibilityProperty, Visibility.Visible); } else { _rightDataGrid.SetCurrentValue(VisibilityProperty, Visibility.Collapsed); } } }
public override void OnApplyTemplate() { base.OnApplyTemplate(); if (_scrollViewer != null) { _scrollViewer.ScrollChanged -= ScrollViewer_ScrollChanged; } if (_rightScrollViewer != null) { _rightScrollViewer.ScrollChanged -= RightScrollViewer_ScrollChanged; } if (_rightDataGrid != null) { _rightDataGrid.ScrollViewerChanged -= ScrollViewerChanged; _rightDataGrid.SelectionChanged -= RightDataGrid_SelectionChanged; } _scrollViewer = GetTemplateChild(DG_ScrollViewer) as ScrollViewer; if (_scrollViewer != null) { _scrollViewer.ScrollChanged += ScrollViewer_ScrollChanged; } _rightDataGrid = GetTemplateChild(PART_Right) as DataGridScrollView; if (_rightDataGrid != null) { _rightDataGrid.ScrollViewerChanged += ScrollViewerChanged; _rightDataGrid.SelectionChanged += RightDataGrid_SelectionChanged; } SelectionChanged += DataGridRightFrozen_SelectionChanged; } private void ScrollViewerChanged(ScrollViewer viewer) { _rightScrollViewer = viewer; _rightScrollViewer.ScrollChanged += RightScrollViewer_ScrollChanged; } private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) { _rightScrollViewer?.ScrollToVerticalOffset(_scrollViewer.VerticalOffset); } private void RightScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) { _scrollViewer?.ScrollToVerticalOffset(_rightScrollViewer.VerticalOffset); } private void RightDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { SetCurrentValue(SelectedItemProperty, _rightDataGrid.SelectedItem); } private void DataGridRightFrozen_SelectionChanged(object sender, SelectionChangedEventArgs e) { _rightDataGrid.SetCurrentValue(SelectedItemProperty, SelectedItem); }
4、接著去到HandyControl的開源庫那裡,找到DataGrid的樣式,然後複製到專案中
5、然後對原來的Style進行修改,對ControlTemplate的佈局新增上作為固定列的DataGrid
6、至此,自定義支援右側列固定的DataGrid就完成了,效果如下:
7、程式碼地址:https://gitee.com/liulang_g/data-grid-demo