隐藏/禁用 DataGridView 列/行调整大小行

Posted

技术标签:

【中文标题】隐藏/禁用 DataGridView 列/行调整大小行【英文标题】:Hide/Disable DataGridView Column/Row Resizing Line 【发布时间】:2020-08-23 14:53:12 【问题描述】:

是否有人知道在调整 datagridview 行和列的大小时禁用出现的行的方法。这条线闪烁很多,所以我宁愿自己画自己的实线并禁用默认线。

我希望通过绘制我自己的粗线(我已经完成了)它会在默认闪烁的一条上方绘制,但不幸的是两条线都会出现,闪烁的一条通常会稍微出现在右侧或左侧我的固体。我不认为它是相关的,而是用于绘制下面的线的代码。

Private Sub DataGridView1_Paint(sender As Object, e As PaintEventArgs) Handles DataGridView1.Paint

    If resizingColumns = True Then

        Dim penRed As Pen
        penRed = New Pen(color.Red, 3)

        Dim cursorPosition As Integer = Me.DataGridView1.PointToClient(New Point(Cursor.Position.X, Cursor.Position.Y)).X

        e.Graphics.DrawLine(penRed, cursorPosition, 0, cursorPosition, Me.DataGridView1.Size.Height)

    End If

End Sub

我能想到的唯一其他选择(我真的不想这样做)是将 AllowUserToResizeColumns 设置为 false(这也会隐藏列调整大小行),然后使用鼠标事件以编程方式调整列大小。

任何帮助或指导将不胜感激。

【问题讨论】:

这条线无法控制。我认为您的粗线与闪烁的线没有完全重叠,因为您使用的是鼠标指针 X 坐标,而不是单元格之间实际分隔符的 X 坐标(但我很确定它无论如何都会闪烁)。在这种情况下,我什至不确定自己管理鼠标事件是否值得,这需要大量调整代码(也就是很多意想不到的错误)。没有该功能的 3d 派对控件怎么办? 嗨 FandangoOnCore,是的,你是对的,这条线并不是完全重叠的,而且无论如何都会出现闪烁的线。 3rd 方控制是什么意思? 我的意思是其他公司的一些其他网格控件。也许他们的一些网格没有那条移动线,或者至少它是可定制的。您可以参考此 [***.com/questions/6008226/… 上的答案以获取这些 3d 部分网格控件中的一些链接(抱歉,我在上一个答案中输入了类型)。 【参考方案1】:

我注意到,如果您创建派生 DataGridView 并启用其 DoubleBuffered 属性,则不会出现调整大小指示线。使用该信息,我创建了以下概念验证控件,可用于代替基本 DataGridView 控件。

Public Class MyDGV : Inherits DataGridView
  Private resizePen As New Pen(Color.Red, 3)

  Public Sub New()
    MyBase.New
    DoubleBuffered = True
  End Sub

  Protected Overrides Sub Dispose(disposing As Boolean)
    MyBase.Dispose(disposing)
    If resizePen IsNot Nothing Then
      resizePen.Dispose()
      resizePen = Nothing
    End If
  End Sub

  Private ReadOnly Property InColumnResize As Boolean
    Get
      Return (MouseButtons = MouseButtons.Left) AndAlso (Cursor = Cursors.SizeWE)
    End Get
  End Property

  Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
    MyBase.OnMouseMove(e)
    If InColumnResize Then Invalidate()
  End Sub

  Protected Overrides Sub OnPaint(e As PaintEventArgs)
    MyBase.OnPaint(e)
    If InColumnResize Then
      Dim cursorPosition As Integer = Me.PointToClient(New Point(Cursor.Position.X, Cursor.Position.Y)).X
      e.Graphics.DrawLine(resizePen, cursorPosition, 0, cursorPosition, Me.Size.Height)
    End If
  End Sub

End Class

我需要在调整大小时Invalidate 控件以删除先前的绘制线。也许只是使上一行更好的区域无效。

InColumnResize 的属性无疑是一个完整的黑客工作;也许你用来设置resizingColumns 的逻辑更好。

【讨论】:

【参考方案2】:

首先,很抱歉我将用 C# 发布我的示例,请使用Telerik's Converter 将代码转换为 VB.NET

最近,我一直在处理这个问题。我已经研究并记录了整个框架,只是想看看有没有什么好的方法可以实现它,没有。

当我看到您的问题时,我决定花一个小时,集中精力并挖掘更多内容,并在我一直使用的另一种混乱方式之前找到了一种非常混乱的实现方式。对于感兴趣的程序员,到目前为止我所做的是通过反射或继承将双缓冲激活到 DataGridView 控件,并与WS_EX_COMPOSITED 激活混合。

像这样工作:

public class DataGridViewV2 : DataGridView


    protected override CreateParams CreateParams
    
        get
        
            CreateParams cp = base.CreateParams;
            cp.ExStyle = cp.ExStyle | 0x02000000;
            return cp;
        
    

    public DataGridViewV2()
    
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.DoubleBuffer, true);
    

这大大减少了垂直拆分器的出现。在大多数情况下,它就足够了,除非它真的会影响您的设计不一致或者您是一个完美主义者。

好的,现在进入我刚刚找到的当前方法:

This 是导致我们丑陋问题的主要方法,它是一个私有方法,我们无法对其进行操作。我一直在从一个代码跳到另一个代码,发现它依赖于一个名为currentColSplitBar 的私有变量,它是否会被绘制。大奖!我们所要做的就是使用反射,将变量编辑为始终坚持 -1 值,以反对在 PaintGrid 方法上绘制它的条件,它永远不会出现。

当我们点击一​​个单元格的可调整大小的分隔线时,分割线的绘制就开始了,它一直持续到我们释放点击,所以很自然地,我们想要在 MouseDown 事件和 MouseMove 事件上编辑变量。所以我们要做的就是重用以前的方法,同时为这些事件分配新的处理程序。

 public class DataGridViewV2 : DataGridView


    public DataGridViewV2()
    
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.UserPaint, true);
        SetStyle(ControlStyles.DoubleBuffer, true);

        MouseDown += (sender, e) => PreventXOR_Region();
        MouseMove += (sender, e) => PreventXOR_Region();
    

    private void PreventXOR_Region()
    
        FieldInfo field = typeof(DataGridView).GetField("currentColSplitBar", BindingFlags.Instance | BindingFlags.NonPublic);
        field.SetValue(this, -1);
    

    protected override CreateParams CreateParams
    
        get
        
            CreateParams cp = base.CreateParams;
            cp.ExStyle = cp.ExStyle | 0x02000000;
            return cp;
        
    

乱七八糟,但它有效!

【讨论】:

以上是关于隐藏/禁用 DataGridView 列/行调整大小行的主要内容,如果未能解决你的问题,请参考以下文章

C# .NET中DataGridView 的所有属性?

转:DataGridView列的宽度行的高度自动调整

c# datagridview 根据内容自动调整行高

DataGridView 行列的隐藏和删除

关于DataGridView控件的几个属性

VB2010中datagridview行标题及列标题如何改变背景色