我正在实现一个继承自Control
的自定义控件。我希望它是可聚焦的(它是一种列表框)。
在构造函数中,我做
SetStyle(ControlStyles.Selectable, true);
我现在可以使用Tab导航到控件。
但是,当控件收到鼠标单击时,它不会自动声明焦点。当然,我可以解决这个问题:
protected override void OnMouseDown(MouseEventArgs e)
{
Focus();
base.OnMouseDown(e);
}
但这感觉就像一个不应该是必需的kludge。这真的是要走的路吗?或者有没有办法告诉Control
在收到鼠标点击时自动声明焦点?
答案 0 :(得分:4)
拆卸救援!事实证明
SetStyle(ControlStyles.UserMouse, true);
诀窍。
具有讽刺意味的是,我读过documentation:
UserMouse
:如果为true,则控件执行自己的鼠标处理,操作系统不处理鼠标事件。
这似乎与我想要的完全相反,所以我只尝试将其设置为false
...方式去,WinForms文档。
答案 1 :(得分:2)
是的,你应该做什么。有许多控件没有一个有意义的方法来获得焦点。 PictureBox,Panel就是很好的例子。任何派生自ContainerControl的东西。因此,Control.OnMouseDown()不会在OnMouseDown()中自动调用Focus()。
仅仅重写OnMouseDown方法是不够的,您还应该向用户说明您的控件具有焦点。所以她会知道键盘敲击的位置。这需要重写OnPaint(),以便您可以绘制焦点矩形。 ControlPaint.DrawFocusRectangle()是一个样板实现。
但是,如果您使用键盘消息做一些有意义的事情,那么获得焦点真的很有用。因此,您还必须重写OnKeyDown和/或OnKeyPressed。并向用户显示反馈,以便她可以看到她输入的内容。如果您没有有用的实现,则不应该关注焦点。这就是PictureBox没有的原因。
答案 2 :(得分:0)
在FrameWork 3.5的WinForms项目中编译
将Control1的实例从ToolBox拖到Form Surface ...确保其TabStop属性设置为'true
在表单上放置一些其他控件。
验证当Control1的实例被选项卡为时:它显示一个选择矩形,当您从中“标记”时它会消失。
验证您是否单击Control1实例显示选择矩形,如果单击其他控件则消失。
namespace testFocusableControl
{
// VS Studio 2010 RC1 : Tested against FrameWork 3.5 Full (not 'Client)
public class Control1 : Control
{
public Control1()
{
SetStyle(ControlStyles.UserMouse, true);
}
protected override void OnLostFocus(EventArgs e)
{
this.Invalidate();
base.OnLostFocus(e);
}
protected override void OnGotFocus(EventArgs e)
{
this.Invalidate();
base.OnGotFocus(e);
}
protected override void OnPaint(PaintEventArgs e)
{
if (this.Focused)
{
ControlPaint.DrawFocusRectangle(e.Graphics, this.ClientRectangle, Color.Red, Color.Blue);
}
base.OnPaint(e);
}
}
}
这里唯一的“松散结束”是这个解决方案会在鼠标点击时显示选择矩形,但我没有像Thomas建议的那样实现任何MouseDown代码。
注意,如果你将Control控制在'ContainerControl via'SetStyle(ControlStyles.ContainerControl,true)之上;并添加一些其他控件,即使你将添加的控件的TabStop属性设置为'false:...如果它被点击...它将获得焦点,你将失去ContainerControl上显示的焦点矩形。 / p>