【问题标题】:Is it possible to extend the DataGridView control without subclassing?是否可以在没有子类化的情况下扩展 DataGridView 控件?
【发布时间】:2015-08-07 11:21:38
【问题描述】:

简短版:

有没有一种方法可以在 DataGridView 控件上添加属性并覆盖 OnMouseDown / OnMouseUp 功能,而无需创建我自己的扩展 DataGridView 的控件?

长版(附解释):

我正在现有应用程序的网格之间实现多行的拖放移动。我有一个具有所需功能的扩展 DataGridView 控件,它可以完美地在此网格的实例之间移动行。

这是扩展的 DGV 类代码:

public partial class DragDropGrid : DataGridView
{
    /// <summary>
    /// When set, the mouse down event and click events don't happen until the mouse button is released.
    /// </summary>
    public bool DelayMouseDown = false;

    public int MouseDownRowIndex = -1;

    protected override void OnMouseDown(MouseEventArgs e)
    {
        if (DelayMouseDown)
        {
            return;
        }
        base.OnMouseDown(e);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        if (DelayMouseDown)
        {
            base.OnMouseDown(e);
        }
        base.OnMouseUp(e);
    }
}

但是,我还有另一个网格(自定义 UserControl),我需要能够处理相同的拖放功能。这个网格是来自我们的基类套件的复合用户控件,并且有一个 DataGridView 以及控件上的一堆其他内容。

我尝试了以下方法来实现与我已成功扩展的基本 DataGridView 相同的功能,但没有成功:

  • 将我的基类网格扩展为与 DataGridView 相同。这 不能像覆盖 MouseDown / MouseUp 方法那样工作 自定义 UserControl,而不是位于控件上的 DataGridView - 所以 单击网格不会触发覆盖的方法。

  • 使用属性/重写方法更新基类网格。 这和上面有同样的问题; MouseDown / MouseUp 是 覆盖 UserControl 的方法,因此在
    上单击 DataGridView 控件不会命中被覆盖的方法。

我希望只添加属性并覆盖整个 DataGridView 类的方法,以便自定义 UserControl 上的 DGV 可以与其他 DataGridView 控件一起使用该功能。

救命!

【问题讨论】:

  • 鼠标操作不能直接添加handler吗?如果你的 DataGridView 被称为 dgv,那么 dgv.OnCellMouseDown += MyHandlerMethodName?
  • 我的问题可能不够清楚,但我不想订阅 MouseDown / MouseUp 事件,我想覆盖网格的 OnMouseDown / OnMouseUp 函数。我将在问题的扩展代码中进行编辑,以便您了解我的意思。
  • 抱歉,我误会了。粗略一看,Luaan 的回答似乎是一个不错的方法。

标签: c# winforms datagridview


【解决方案1】:

看来你的用户控件里面有一个DataGridView

因此,不要绑定现有的MouseDown/MouseUp 事件等(确实是用户控件的事件,而不是网格),只需将新事件添加到您的用户控件,然后让它们传递给网格视图。例如:

public event MouseEventHandler GridMouseDown 
{ 
  add { dataGrid.MouseDown += value; }
  remove { dataGrid.MouseDown -= value; }
}

编辑:

好的,既然您专门询问了有关覆盖 OnMouseDown 方法的问题,答案很简单:创建派生类型是唯一的方法。

您可以使用一些非常肮脏的技巧来解决这个问题,但对于像这样微不足道的事情来说,这是一个坏主意。

【讨论】:

  • 我想你可能被我糟糕的措辞误导了——对不起!我不想对这些事件做任何事情(即使我确实说过事件——我会对其进行编辑以澄清);我要覆盖处理鼠标按下和鼠标按下事件的基础功能。我的想法是我可以在我的应用程序的鼠标按下事件中将“DelayMouseDown”属性设置为 true,然后在随后的单击中,鼠标按下不会发生(因此选择不会改变)直到鼠标按钮已发布。
  • @PauLF 好吧,那是不可能的。您不使用通常的拖放 API 是否有原因?
  • 在尝试使用多选和拖放操作时,DGV 处理鼠标点击的方式存在缺陷。例如:选择网格中的多行,然后尝试开始拖动 - 开始拖动的左键单击也调用 MouseDown 和 Click,触发 SelectionChanged,并将所选行更改为仅发生 MouseDown 的一行。覆盖 MouseDown 允许您在开始拖动时保留行选择。 stackoverflow.com/questions/1942636/…
  • 刚刚看到您的编辑。我只需要硬着头皮在自定义 UserControl 上更改 DGV。感谢您对此的帮助。
猜你喜欢
  • 2016-03-11
  • 2012-08-11
  • 2012-12-13
  • 2013-06-27
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多