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

5

有没有方法可以禁用调整 datagridview 行和列大小时出现的线条?此行会频繁闪烁,所以我宁愿自己画一条实线并禁用默认线条。

enter image description here

我希望通过绘制自己的粗线条(已完成)来覆盖默认闪烁的线条,但不幸的是两条线都会出现,通常默认线条稍微偏右或偏左于我的实线。我认为下面的代码是绘制线条的代码,但这可能不相关。

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坐标(但我相当确定它仍然会闪烁)。在这种情况下,我甚至不确定自己管理鼠标事件是否值得,这将需要大量调整代码(即很多意外的错误)。使用一个没有该功能的第三方控件怎么样? - FandangoOnCore
嗨,FandangoOnCore,是的,你说得对,这条线不是完全重叠的,闪烁的线条仍然会出现。你所说的第三方控件是什么意思? - Jarron
我的意思是其他公司的一些其他网格控件。也许他们的某些网格没有那个移动线,或者至少可以自定义。您可以参考此[https://dev59.com/fG025IYBdhLWcg3wblc3]上的答案,获取一些这些第三方网格控件的链接(抱歉,我在之前的回答中打错了)。 - FandangoOnCore
2个回答

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

我需要在调整大小期间使控件无效,以删除先前绘制的线条。也许只需使先前线条所在的区域无效更好。 InColumnResize 属性显然是一个完全的 hack 作业;也许你用来设置 resizingColumns 的逻辑更好。

1

首先,我很抱歉我的示例是用C#编写的,请使用Telerik的转换器将代码转换为VB.NET。

最近,我一直在处理这个问题。我研究和记录了整个框架,只是想看看是否有实现它的好方法,但没有找到。

当我看到你的问题时,我决定花一个小时,专注地挖掘一些更多的东西,并发现了一种非常混乱的方法来实现它,这比我一直在使用的另一种混乱的方法更加混乱。对于感兴趣的程序员,到目前为止,我所做的事情是通过反射或继承激活Double Buffering到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);
    }
}

这大大减少了垂直分隔线的显示。在大多数情况下,除非它影响了你的设计不一致性或者你是一个完美主义者,否则它已经足够了。
好的,现在我们来介绍我刚发现的当前方法: 这个 是主要绘制我们的丑陋问题的方法,它是私有的,我们无法操纵它的功能。我已经跳来跳去找到了它依赖于一个叫做 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;
        }
    }
}

混乱,但它可以工作!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接