【问题标题】:Can I use a DrawItem event handler with a CheckedListBox?我可以将 DrawItem 事件处理程序与 CheckedListBox 一起使用吗?
【发布时间】:2013-09-14 12:41:14
【问题描述】:

我想覆盖将项目添加到选中列表框时显示的文本。现在它正在使用 obj.ToString(),但我想附加一些文本,而不更改对象的 ToString 方法。我已经看到处理 ListBox 的 DrawItem 事件的示例,但是当我尝试实现它们时,我的事件处理程序没有被调用。我注意到 Winforms 设计器似乎不允许我为 DrawItem 事件分配处理程序。固执,我只是自己加了代码

        listbox1.DrawMode = DrawMode.OwnerDrawVariable;
        listbox1.DrawItem += listbox1_DrawItem;

我是在尝试做不可能的事吗?

【问题讨论】:

  • 您可能对better solution 对此问题感兴趣(以及您能想到的任何其他特定于 UI 的问题)

标签: winforms c#-4.0 checkedlistbox ondrawitem


【解决方案1】:

并非不可能,但非常困难。您的建议不起作用,请注意类 CheckedListBox 中方法 DrawItem 的元数据:

// Summary:
//     Occurs when a visual aspect of an owner-drawn System.Windows.Forms.CheckedListBox
//     changes. This event is not relevant to this class.
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public event DrawItemEventHandler DrawItem;

因此,您唯一的选择是从CheckedListBox 派生您自己的类,在我有限的测试中,这将是一条漫长的道路。您可以简单地处理绘图,如下所示:

public class CustomCheckedListBox : CheckedListBox
{
    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        String s = Items[e.Index].ToString();
        s += "APPEND";  //do what you like to the text
        CheckBoxState state = GetCheckBoxState(e.State);  // <---problem
        Size glyphSize = CheckBoxRenderer.GetGlyphSize(e.Graphics, state);
        CheckBoxRenderer.DrawCheckBox(
            e.Graphics, 
            e.Bounds.Location, 
            new Rectangle(
                new Point(e.Bounds.X + glyphSize.Width, e.Bounds.Y), 
                new Size(e.Bounds.Width - glyphSize.Width, e.Bounds.Height)), 
            s, 
            this.Font, 
            false,
            state);
    }
}

注意方法GetCheckBoxState()。你在DrawItemEventArgs 中得到的是DrawItemState,而不是你需要的CheckBoxState,所以你必须翻译,这就是我开始走下坡路的地方。

士兵,如果你愿意,这应该可以让你开始。但我认为这将是一条混乱而漫长的道路。

【讨论】:

  • +1,感谢您的努力并提出了一个不那么简单的代码。但是我认为您(= OP)甚至不应该考虑依赖绘图事件的选项,如果他想要的是影响文本。声明“我不希望 ToString() 方法返回修改”对我来说不是一个理由(为什么不覆盖 ToString() 方法?)。我并不是仅仅针对这种特定情况说所有这些,而是​​总的来说:更好地使用绘制/绘制事件来绘制/绘制(= 颜色、轮廓等)和文本来编写。这会更容易,而且很可能更可靠。
  • @varocarbas 我不反对。但鉴于 OP 的限制,这是唯一可用的其他课程。
【解决方案2】:

我在 DonBoitnotts 回答中继续工作。

“GetCheckBoxState”是使用非常有限的集合实现的,只有两个状态。

var state = GetItemChecked(e.Index) ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;

复选框垂直对齐,文本左对齐。

var b = e.Bounds;
int checkPad = (b.Height - glyphSize.Height) / 2;
CheckBoxRenderer.DrawCheckBox(g, new Point(b.X + checkPad, b.Y + checkPad),
    new Rectangle(
        new Point(b.X + b.Height, b.Y),
        new Size(b.Width - b.Height, b.Height)),
    text, this.Font, TextFormatFlags.Left, false, state);

【讨论】:

  • 重要提示:为避免文本中出现奇怪的效果(视觉效果如粗体),代码必须以 e.DrawBackgroud(); 开头
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
相关资源
最近更新 更多