自定义带边框颜色的ListBox后无法使用原控件属性与方法
解决自定义ListBox无法继承原生属性方法的问题
问题根源在于你当前的自定义控件继承的是UserControl,内部嵌套ListBox相当于做了一层封装,外部无法直接访问原生ListBox的Items、Add()、Clear()等成员。最直接的解决方案是让自定义控件直接继承原生ListBox,而非UserControl,这样就能天然继承ListBox的所有属性和方法,同时实现自定义边框需求。
修改后的完整代码如下:
class CustomListBox : ListBox { //Fields private Color borderColor = Color.MediumSlateBlue; private int borderSize = 1; //Properties [Category("Custom")] public Color BorderColor { get { return borderColor; } set { borderColor = value; Invalidate(); // 修改属性后触发重绘更新边框 } } [Category("Custom")] public int BorderSize { get { return borderSize; } set { borderSize = value; Invalidate(); // 修改属性后触发重绘更新边框 } } public CustomListBox() { this.BorderStyle = BorderStyle.None; // 隐藏原生边框 this.DrawMode = DrawMode.OwnerDrawFixed; this.ForeColor = Color.FromArgb(249, 249, 249); this.FormattingEnabled = true; this.ItemHeight = 24; this.MinimumSize = new Size(200, 30); this.Size = new Size(200, 30); this.Font = new Font(this.Font.Name, 12F); this.DrawItem += CustomListBox_DrawItem; } // 项绘制逻辑 private void CustomListBox_DrawItem(object sender, DrawItemEventArgs e) { Color backgroundColor = Color.FromArgb(50, 50, 50); Color horizontalColor = Color.FromArgb(100, 100, 100); if (e.Index >= 0) { using (SolidBrush sb = new SolidBrush((e.State & DrawItemState.Selected) == DrawItemState.Selected ? horizontalColor : backgroundColor)) { e.Graphics.FillRectangle(sb, e.Bounds); } string text = this.Items[e.Index].ToString(); using (SolidBrush tb = new SolidBrush(e.ForeColor)) { e.Graphics.DrawString(text, e.Font, tb, this.GetItemRectangle(e.Index).Location); } } } // 重绘自定义边框 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); using (Pen penBorder = new Pen(borderColor, borderSize)) { penBorder.Alignment = PenAlignment.Inset; // 调整坐标避免边框被控件边缘截断 e.Graphics.DrawRectangle(penBorder, borderSize / 2f, borderSize / 2f, this.Width - borderSize, this.Height - borderSize); } } }
关键修改说明:
- 继承关系改为
ListBox,直接获得原生ListBox的所有属性(如Items、SelectedIndex)和方法(如Add()、Clear())。 - 移除内部嵌套的
Listb控件,所有操作直接作用于自定义控件本身。 - 在
BorderColor和BorderSize的setter中添加Invalidate(),修改属性时自动触发边框重绘。 - 调整边框绘制坐标,避免边框被控件边缘截断。
- 保留原有项绘制逻辑,仅将操作对象改为当前控件。
修改完成后,你可以像使用原生ListBox一样调用CustomListBox.Items.Add("测试内容")、CustomListBox.Items.Clear()等方法,同时保留自定义边框和项样式的功能。
内容的提问来源于stack exchange,提问作者Filipe
相关产品推荐
相关产品推荐

