C#自定义ListBox控件Click事件无法触发问题求助
自定义UserControl的Click事件未触发的解决方法
问题描述
我实现了一个继承自UserControl的CustomListBox控件,内部封装了ListBox。在窗体中使用该控件(命名为MainLB)并绑定Click事件后,点击控件时MainLB_Click事件未触发,推测点击事件被内部ListBox捕获。请问如何让自定义控件的Click事件正常工作?
CustomListBox实现代码
class CustomListBox : UserControl { //Fields private Color borderColor = Color.MediumSlateBlue; private int borderSize = 1; //Items private ListBox Listb; //Properties [Category("Custom")] public Color BorderColor { get { return borderColor; } set { borderColor = value; } } [Category("Custom")] public int BorderSize { get { return borderSize; } set { borderSize = value; this.Padding = new Padding(borderSize);//Border Size AdjustListBoxDimensions(); } } [Category("Custom")] public override Color BackColor { get { return base.BackColor; } set { this.Listb.BackColor = value; base.BackColor = value; } } public void Add(object item) { this.Listb.BeginUpdate(); this.Listb.Items.Add(item); this.Listb.EndUpdate(); } public void Clear() { this.Listb.BeginUpdate(); this.Listb.Items.Clear(); this.Listb.EndUpdate(); } public int SelectedIndex() { return this.Listb.SelectedIndex; } public object Item(int index) { return this.Listb.Items[index]; } // List Properties public CustomListBox() { Listb = new ListBox(); this.SuspendLayout(); // ListBox Listb.BorderStyle = BorderStyle.None; Listb.DrawMode = DrawMode.OwnerDrawFixed; Listb.Font = new Font("Cascadia Mono", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); Listb.ForeColor = Color.FromArgb(((int)(((byte)(249)))), ((int)(((byte)(249)))), ((int)(((byte)(249))))); Listb.FormattingEnabled = true; Listb.ItemHeight = 24; Listb.Location = new Point(0,0); Listb.Name = "CustomListBox"; Listb.Size = new Size(235, 936); Listb.DrawItem += new DrawItemEventHandler(Listb_DrawItem); Listb.Dock = DockStyle.Fill; Listb.BackColor = BackColor; Controls.Add(Listb); ResumeLayout(); AdjustListBoxDimensions(); } // Highlight event private void Listb_DrawItem(object sender, DrawItemEventArgs e) { Color backgroundColor = Color.FromArgb(50, 50, 50); Color horizontalColor = Color.FromArgb(100, 100, 100); if (e.Index >= 0) { SolidBrush sb = new SolidBrush(((e.State & DrawItemState.Selected) == DrawItemState.Selected) ? horizontalColor : backgroundColor); e.Graphics.FillRectangle(sb, e.Bounds); string text = Listb.Items[e.Index].ToString(); SolidBrush tb = new SolidBrush(e.ForeColor); e.Graphics.DrawString(text, e.Font, tb, Listb.GetItemRectangle(e.Index).Location); } } //Adjust Dimension (Still in test) private void AdjustListBoxDimensions() { Listb.Location = new Point() { X = this.Width - this.Padding.Right - Listb.Width, Y = Listb.Height }; } // Draws the border protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics graph = e.Graphics; //Draw border using (Pen penBorder = new Pen(borderColor, borderSize)) { penBorder.Alignment = PenAlignment.Inset; graph.DrawRectangle(penBorder, 0, 0, this.Width - 0.5F, this.Height - 0.5F); } } }
窗体绑定事件代码
private void MainLB_Click(object sender, EventArgs e) { string text = MainLB.Item(MainLB.SelectedIndex()).ToString(); }
解决方法
WinForms中子控件会优先处理鼠标事件,不会自动将事件冒泡到父级UserControl,因此需要手动将内部ListBox的Click事件转发给CustomListBox的Click事件。
具体修改
在CustomListBox的构造函数中,给内部ListBox添加Click事件处理逻辑,触发父控件的OnClick方法:
public CustomListBox() { Listb = new ListBox(); this.SuspendLayout(); // 保留原有ListBox配置代码... // 添加以下代码,转发Click事件 Listb.Click += (sender, e) => base.OnClick(e); Controls.Add(Listb); ResumeLayout(); AdjustListBoxDimensions(); }
原理说明
当用户点击内部ListBox时,会触发Listb的Click事件,通过Lambda表达式调用CustomListBox的OnClick方法,该方法会触发CustomListBox自身的Click事件,从而让窗体中绑定的MainLB_Click事件正常执行。
如果需要同时处理其他鼠标事件(如MouseDoubleClick),可以用同样的方式转发:
Listb.MouseDoubleClick += (sender, e) => base.OnMouseDoubleClick(e);
内容的提问来源于stack exchange,提问作者Filipe
相关产品推荐
相关产品推荐

