【问题标题】:how to redirect events at a usercontrol如何在用户控件上重定向事件
【发布时间】:2014-08-21 13:33:20
【问题描述】:

我有一个用户控件,很简单,只有一个标签和一个图片框,它们是停靠的,你甚至看不到底层 大多数事件从未发生(点击、悬停等)

我认为(我可能错了),这是因为事件不会被触发,因为它们被点击在标签或图片框上而不是在背景上

我需要以某种方式重定向这些事件(即在用户控件中创建该事件并以某种方式将它们重定向到我的代码,我的代码是指使用它们的表单)或任何其他方式来捕获这些事件

我已经看到了 5 个关于同一问题的主题,但没有一个得到解决,有什么解决方法吗?

【问题讨论】:

  • 解决方法可能是转发事件。将新事件添加到您的控件并在控件事件处理程序中提升它。
  • 我知道并且应该可以,但现在我需要订阅这两个事件,我的自定义事件和其他本地事件,我还必须为每个本地事件创建一个自定义事件,如果我有到,但让我们看看是否有更神奇的优雅解决方案:)
  • 我明白了。看看我发现了什么here。看起来“透明”控件可能适合您的需求,并且更神奇:)

标签: c# .net winforms user-controls


【解决方案1】:

您需要使用以下代码将标签和图片框的Click 事件重定向到用户控件的OnClick 事件:

public UserControl1()
{
   InitializeComponent();

   this.label1.Click += myClickEvent;
   this.pictureBox1.Click += myClickEvent;
}

private void myClickEvent(object sender, EventArgs e)
{
   this.OnClick(e);
}

【讨论】:

  • + 这是一个不错的解决方案。您不需要任何自定义事件。
  • 好吧,对不起,我删除了我的旧评论(我很困惑,不得不删除它,当时不知道你发布了)你的答案是最好的,最简单的,最优雅的:) 谢谢你
【解决方案2】:

Matin Lotfaliee 的回答绝对正确,但在我的情况下,如果我想将事件从一个控件转发到“OtherControl”,您可能更喜欢单行:

this.OtherControl.Click += (s, e) => { this.OnClick(e); };

【讨论】:

    【解决方案3】:

    如果您可以继承Label 和PictureBox,则继承它们并覆盖WndProc 并执行以下操作。

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == (int)WindowsMessage.WM_NCHITTEST)
        {
            m.Result = (IntPtr)(-1);//Transparent
            return;
        }
        base.WndProc(ref m);
    }
    

    如果没有,请使用此

    public partial class MyUserControl : UserControl
    {
        private TransparentWindow label;
        private TransparentWindow pic;
    
        public MyUserControl()
        {
            InitializeComponent();
        }
    
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
    
            label = new TransparentWindow(label1);
            pic = new TransparentWindow(pictureBox1);
        }
    }
    
    class TransparentWindow : NativeWindow
    {
        public TransparentWindow(Control control)
        {
            this.AssignHandle(control.Handle);
        }
    
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == (int)WindowsMessage.WM_NCHITTEST)
            {
                m.Result = (IntPtr)(-1);//Transparent
                return;
            }
            base.WndProc(ref m);
        }
    }
    

    WindowMessage枚举可以找到here

    Related question

    【讨论】:

    • @MatinLotfaliee I remember you你还有报仇吗?
    • 只是想和我的朋友打个招呼。我知道我没有你知识渊博,但你当时的评论并不公平。
    • @MatinLotfaliee 算了,伙计。如果你能教我一些我很乐意学习的东西。 Sameway 如果我能教你一些东西也很高兴.. 那天我觉得它很丑,然后说。如果您提供好的答案,我会赞成。没什么好说的,我希望你有一天会意识到它真的不优雅,到时候你会记得我。还有……你好,我的朋友……:)
    • 嗯,我的意思是你的粗鲁让我当时作为一个新人感到震惊。在阅读了您的理由并自己进行了测试后,我意识到我的答案很丑陋。顺便说一句,作为 WindowMessages 的专家,你能帮我this one吗?
    猜你喜欢
    • 2021-06-28
    • 2016-01-24
    • 2013-11-24
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    • 2015-02-27
    • 1970-01-01
    相关资源
    最近更新 更多