You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义带边框颜色的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 05:55:16