【问题标题】:MouseWheel of parent panel - Pass event from child父面板的 MouseWheel - 从子传递事件
【发布时间】:2019-07-20 12:22:12
【问题描述】:

我有一个自定义面板,其中包含 4 个标签(在粘贴的示例中,我已删除了我未使用的 2 个标签的定义)。 这个自定义面板被动态添加到面板中,就像我在数组中拥有的许多记录一样。 父面板启用了水平滚动 = false,因为我应该只垂直滚动。 一切正常,因为我可以在垂直滚动条上使用鼠标,并且可以滚动面板容器。但是当我想使用鼠标滚轮滚动所有自定义面板(子对象)时,它什么也不做。 我已经尝试了许多适用于该网站上其他人的解决方案,但它们都不适合我,我不知道为什么。

我了解到面板必须具有焦点才能滚动,并且我必须将 OnMouseWheel 事件传递给父级,子级。但是我做不到,我不知道该怎么做。

我的自定义面板(子):

public class PlaylistRecords : Panel
{
    public Label lblRecordNumber { get; private set; }

    private Label lblRecordName;

    public static int RecordNumber { get; set; }
    public static String RecordName { get; set; }

    public PlaylistRecords(
            int RecordNumber, 
            String RecordName
            )
    {
        InitializeComponent();
        this.Size = new System.Drawing.Size(800,50);
        this.BackColor = System.Drawing.Color.FromArgb(20,20,20);

        PlaylistRecords.RecordNumber = RecordNumber;
        PlaylistRecords.RecordName = RecordName;

        this.lblRecordNumber.Text = PlaylistRecords.RecordNumber.ToString()+".";
        this.lblRecordName.Text = PlaylistRecords.RecordName;

        this.lblRecordNumber.Location = new System.Drawing.Point(2, (int)(this.Height - this.lblRecordNumber.Height) / 2);
        this.lblRecordName.Location = new System.Drawing.Point(
                    this.lblRecordNumber.Location.X+ this.lblRecordNumber.Width+2, 
                    (int)(this.Height - this.lblRecordName.Height) / 2);

    }

    private void InitializeComponent()
    {
        this.lblRecordNumber = new myLabel();
        this.lblRecordName = new myLabel();
        this.lblRegistPath = new myLabel();

        this.SuspendLayout();
        // 
        // lblRecordNumber
        // 
        this.lblRecordNumber.Name = "lblRecordNumber";
        this.lblRecordNumber.Size = new System.Drawing.Size(50, 23);

        // 
        // lblRecordName
        // 
        this.lblRecordName.Name = "lblRecordName";
        this.lblRecordName.Size = new System.Drawing.Size(150, 23);

        // 
        // PlaylistRecords
        // 
        this.Controls.Add(this.lblRecordNumber);
        this.Controls.Add(this.lblRecordName);
        this.ResumeLayout(false);

    }
}

【问题讨论】:

  • Win10 之前的 Windows 版本将鼠标滚轮通知发送到具有焦点的控件。这里的关键问题是您使用的任何控件都无法获得焦点。因此,尝试将消息从孩子传递给父母也不是解决方案。创建自己的网格控件绝不是错误的。考虑一个 ListView。或者使用可以获取焦点的面板:stackoverflow.com/questions/3562235/panel-not-getting-focus

标签: c# winforms


【解决方案1】:
this.SetStyle(ControlStyles.Selectable, true);
this.TabStop = true;

在子控件(面板)的构造函数中编写的这两行代码正在完成这项工作。

感谢@Hans Passant 的评论。 :)

【讨论】:

    【解决方案2】:

    如果控件不接受事件,那么它们将被传递给父控件

    lblRecordNumber.Enabled = false;
    lblRecordName.Enabled = false;
    

    或者,您可以将滚动事件传递给称为父控件的包含控件

    internal class myLabel : Label
    {
        const int WM_MOUSEWHEEL = 0x020A;
    
        protected override void WndProc(ref Message m)
        {
    
            if (m.Msg == WM_MOUSEWHEEL)
                m.HWnd = this.Parent.Handle; 
    
            base.WndProc(ref m);
        }
    }
    

    并改用该控件。

    【讨论】:

    • lblRecordNumber 和 lblRecordName 是基于标签的控件。他们没有“IsEnabled”属性。至少 VS2019 没有在智能感知中显示我 :( 此外,您的解决方案覆盖 WndProc 事件不起作用。它什么也没做:(
    • @ValiMaties 我的错误,从内存中写入,它被称为“启用”。
    猜你喜欢
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 2022-11-24
    相关资源
    最近更新 更多