我有一个继承自Button的MyButton类。在这个课程中,我已经放置了其他几个控件(Labels,Progessbar)。这样做的问题是Button上的控件使得无法触发Button.Click或Button.MouseHover事件。我怎样才能实现按钮上的控件只显示但是“事件透明”:标签和progessbar上的单击/悬停与我直接点击/悬停在按钮上(包括发件人和所有内容)相同。像“继承父母的事件”之类的东西。
class MyButton : Button
{
Label foo = new Label();
ProgressBar bar = new ProgessBar();
}
答案 0 :(得分:4)
您应该从UserControl派生,然后将该按钮作为子控件,并在点击事件上冒泡按钮子项。
这link可能比您需要的更多,但这是一个很好的起点。
<强>更新强>
正如所指出的,您可能没有使用ASP.NET。因此here是另一篇讨论不同自定义用户控件的帖子,特别是你所追求的是Composite Control
。这适用于Windows窗体。
答案 1 :(得分:3)
为标签和PB编写Click事件处理程序,让它们调用PerformClick()。
使控件对鼠标透明是可能的,但是很难做到。您必须覆盖WndProc()以捕获WM_NCHITTEST并返回HTTRANSPARENT。全方位更好的解决方案是不使用控件。 Label只是按钮的Paint事件中的TextRenderer.DrawText()。 ProgressBar也不难,e.Graphics.FillRectangle()。
答案 2 :(得分:1)
让子控件成为按钮前面的实际控件(在继承自Button
或UserControl
的类中)可能会让按钮特定事件很难正常工作,就像你一样找到。 (编辑:虽然很难,但这并非不可能 - 请参阅Hans Passant的回答)
作为一种解决方法,您可以将它们自定义绘制到按钮表面上,而不是使用子控件,因为您不需要控件的大部分功能(事件,聚焦等),只需要显示它们。
您可以在班级的OnPaint
方法中进行额外的绘画。类似的东西:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawString("My fake label", Font,
SystemBrushes.ControlText, new Point(10, 10))
// draw progressbar
}
要更新显示,您需要使用Invalidate()
触发按钮的重绘。
请查看Custom Bitmap Button Using C# on CodeProject以获取更完整的示例。
答案 3 :(得分:0)
这个答案刚才在这里,但被删除了:
您可以继承UserControl
吗?这将允许您在控制界面上放置其他控件,包括按钮并订阅他们的事件。
答案 4 :(得分:0)
如果你正在使用WPF,我猜你正在寻找的东西叫做 Bubbled Events 。它是WPF中的一项功能,通过该功能,从控件到其父级的事件冒泡(在您的情况下,它将从您的ProgressBar和Label到您的按钮)。我发现this article on the matter我觉得对你有帮助。
希望这会有所帮助:)