首页 > 其他分享 >WPF随笔收录-DataGrid固定右侧列

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

时间:2024-04-17 16:23:38浏览次数:21  
标签:ScrollChanged void SelectionChanged DataGrid rightDataGrid private WPF 随笔

一、前言

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

 

标签:ScrollChanged,void,SelectionChanged,DataGrid,rightDataGrid,private,WPF,随笔
From: https://www.cnblogs.com/liulangg/p/18140748

相关文章

  • WPF 使用DbUtility 数据库通用操作类
    依赖准备1.在WPF项目内首先通过NuGet包管理器进行安装需要操作的数据库依赖,我这里使用的是SQLite数据库所以安装的是System.Data.SQLite。2.安装后需要下载DbUtility.dll,下边是网盘地址https://www.123pan.com/s/TaoVjv-4aWHv.html3.下载后把文件放到项目根目录下,在软件内引用......
  • WPF中文网随笔(2)
    常用布局控件Panel其实是一个抽象类,不可以实例化,WPF所有的布局控件都从Panel继承而来publicabstractclassPanel:FrameworkElement,IAddChild它继承于FrameworkElement基类和IAddChild接口。所以,所有Panel元素都支持FrameworkElement定义的基本大小调整和定位属性,包......
  • wpf程序修改启动入口注意事项
    如果你在自定义的Main方法中直接使用App类并启动应用程序,但发现App.xaml中定义的资源没有被正确加载,那么问题可能在于如何正确配置App.xaml与你的App类的交互。确保App.xaml文件中的x:Class属性正确指向你的App类。这样,当你创建App类的实例并调用Run方法时,它......
  • WPF随笔收录-实时绘制心率曲线
    一、前言在自己的项目中,涉及到实时心率曲线的绘制,项目上的曲线绘制,一般很难找到能直接用的第三方库,而且有些还是定制化的功能,所以还是自己绘制比较方便。很多人一听到自己画就害怕,感觉很难,今天就分享一个完整的实时心率数据绘制心率曲线图的例子;之前的博客也分享给DrawingVis......
  • WPF/C#实现图像滤镜优化方案:打造炫目视觉体验!
    原因:我之所以想做这个项目,是因为在之前查找关于C#/WPF相关资料时,我发现讲解图像滤镜的资源非常稀缺。此外,我注意到许多现有的开源库主要基于CPU进行图像渲染。这种方式在处理大量图像时,会导致CPU的渲染负担过重。因此,我将在下文中介绍如何通过GPU渲染来有效实现图像的各种滤镜效果......
  • WPF中文网随笔(1)
    前端代码的全称为ExtensibleApplicationMarkupLanguage,简称XAML;<Application.Resources></Application.Resources>前端代码中x:Class="HelloWorld.App",它定义一个名叫App的类型,这个类型位于命令空间HelloWorld之中,与后端代码的namespaceHelloWorld保持一致。我们可以......
  • WPF基础:在Canvas上绘制图形
    Canvas介绍Canvas是WPF(WindowsPresentationFoundation)中的一种面板控件,用于在XAML中布置子元素。它提供了绝对定位的能力,允许元素在自由的二维空间中放置。Canvas上的子元素可以通过指定绝对位置(Left和Top属性)来放置,也可以使用附加属性来指定相对于Canvas的位置。Canvas对于需......
  • 美化一下WPF自带得ToolTip
    对照一下原版和美化以后得版本原版: ---------- 新版: 新增了圆角和阴影效果;第一步:新建项,最下面有一个自定义控件,取名为CornerToolTip。第二步:系统会创建一个CornerToolTip得类,默认继承自Control,我们把Control改成ToolTip:第三步:系统生成CornerToolTip类得同时,还会......
  • wpf datagrid,menuitem, style, export ,show in a another window,mvvm
    //xaml<Windowx:Class="WpfApp58.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.mic......
  • WPF 在后台代码中选中DataGrid的多行
    1///<summary>2///设置datagrid选中多行3///</summary>4///<paramname="listIndex"></param>5privatevoidSetSelectMessageIndex(List<int>listIndex)6{7......