如何解决派生自定义控件 Class 和 Form1.cs 中的事件处理程序之间的冲突

How to resolve conflicts between Derived Custom Control Class and EventHandlers in Form1.cs

public class CustomListView : ListView
{
    public CustomListView()
    {

    }
    private bool ContextAllowed = false;

    public override ContextMenuStrip ContextMenuStrip
    {
        get
        {
            return base.ContextMenuStrip;
        }
        set
        {
            base.ContextMenuStrip = value;
            base.ContextMenuStrip.Opening += ContextMenuStrip_Open;
        }
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            ListViewHitTestInfo test = HitTest(e.X, e.Y); //perform a hit test
            if (test.Item != null) //if it hits an item, display the popup bar
            {
                ContextAllowed = true;
            }
        }
        base.OnMouseDown(e);
    }
    protected override void OnMouseUp(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            ContextAllowed = false; //close the menu
        }
        base.OnMouseUp(e);
    }

    private void ContextMenuStrip_Open(object sender, CancelEventArgs e)
    {
        if (!ContextAllowed)
        {
            e.Cancel = true;
        }
    }
}

问题: 上面的代码是针对一个名为 CustomListView 的 class。它是一个自定义控件,其目的是允许我右键单击一行并对该行执行功能。我成功地将它构建为一个 dll,将它添加到工具箱中,并在我的表单上使用它。我能够像常规 ListView 一样用信息填充它,但是 ContextMenuStrip 的任何右键单击功能都不起作用。

尝试解决方案: 我已将 ContextMenuStrip 分配给 CustomListView 控件。我认为问题是 CustomListView class 中的事件处理程序(即 OnMouseDown 和 OnMouseUp)没有被使用。相反,在 Form1.cs 中使用了具有相同名称的 "other" 事件处理程序,自然不包含任何代码。

我应该将 CustomListView class 中的事件处理程序移动到 Form1.cs 吗?如何使用 CustomListView class 中的事件处理程序?

几件事:

  • 默认情况下,列表视图没有 ContextMenuStrip。这意味着您必须确保它有一个才能使用它。

  • 设置布尔值使其显示后,您必须调用 Show() 方法。事实上,你可能可以省去布尔值,只使用 Show()Close() 方法。

    public class CustomListView : ListView
    {
        public CustomListView()
        {
            cms.Items.AddRange(new ToolStripItem[]{ new ToolStripLabel("Test1"),new ToolStripLabel("Test2")});
            ContextMenuStrip = cms;
        }
        private bool ContextAllowed = false;
        private ContextMenuStrip cms = new ContextMenuStrip();
    
        public override ContextMenuStrip ContextMenuStrip
        {
            get
            {
                return base.ContextMenuStrip;
            }
            set
            {
                base.ContextMenuStrip = value;
                base.ContextMenuStrip.Opening += ContextMenuStrip_Open;
            }
        }
    
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                ListViewHitTestInfo test = HitTest(e.X, e.Y); //perform a hit test
                if (test.Item != null) //if it hits an item, display the popup bar
                {
                    ContextAllowed = true;
                    ContextMenuStrip.Show();
                }
            }
            base.OnMouseDown(e);
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                ContextAllowed = false; //close the menu
            }
            base.OnMouseUp(e);
        }
    
        private void ContextMenuStrip_Open(object sender, CancelEventArgs e)
        {
            if (!ContextAllowed)
            {
                e.Cancel = true;
            }
        }
    }