• WPF随笔收录-DataGrid固定右侧列


    一、前言

    在项目开发过程中,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

     
  • 相关阅读:
    虹科干货 | 虹科工业树莓派Node-RED应用(一) : 低代码实现状态监测
    数据结构与算法--分治策略
    某60区块链安全之整数溢出漏洞实战学习记录
    [数据集][目标检测]塑料纸张垃圾袋检测数据集VOC+YOLO格式1.5w张3类别
    ZMQ之自杀的蜗牛模式和黑箱模式
    【Docker】Docker入门安装指南2022 (Windows版)
    python 异常
    Linux运维实战:CentOS7.6操作系统从入门到精通(16-18)
    我不写单元测试,被批了
    360关键词指数查询易语言代码
  • 原文地址:https://www.cnblogs.com/liulangg/p/18140748