C# 我真的需要在自定义控件的OnMouseDown中调用Focus吗?
我正在实现一个从C# 我真的需要在自定义控件的OnMouseDown中调用Focus吗?,c#,.net,winforms,focus,C#,.net,Winforms,Focus,我正在实现一个从控件继承的自定义控件。我希望它是可聚焦的(它是一种列表框) 在构造函数中,我是这样做的 SetStyle(ControlStyles.Selectable, true); 我现在可以使用Tab导航到控件 但是,当控件收到鼠标单击时,它不会自动声明焦点。当然,我可以解决这个问题: protected override void OnMouseDown(MouseEventArgs e) { Focus(); base.OnMouseDown(e); } 但这感觉
控件
继承的自定义控件。我希望它是可聚焦的(它是一种列表框)
在构造函数中,我是这样做的
SetStyle(ControlStyles.Selectable, true);
我现在可以使用Tab导航到控件
但是,当控件收到鼠标单击时,它不会自动声明焦点。当然,我可以解决这个问题:
protected override void OnMouseDown(MouseEventArgs e)
{
Focus();
base.OnMouseDown(e);
}
但这感觉像是一个不必要的混乱。真的是这样吗?或者有什么方法可以告诉
控件在收到鼠标点击时自动声明焦点?解救!原来
SetStyle(ControlStyles.UserMouse, true);
这就是诀窍
讽刺的是,我在报纸上读到:
UserMouse
:如果为true,则控件自行进行鼠标处理,操作系统不会处理鼠标事件
这似乎与我想要的正好相反,所以我只尝试将其设置为false
。。。干得好,WinForms文档。是的,这就是你应该做的。有许多控件没有一种有意义的方式来获取焦点。PictureBox、Panel都是很好的例子。任何源于集装箱控制的东西。因此,Control.OnMouseDown()不会在OnMouseDown()中自动调用Focus()
仅仅覆盖OnMouseDown方法是不够的,您还应该让用户清楚地知道您的控件具有焦点。所以她会知道键盘笔划的方向。这需要重写OnPaint(),以便可以绘制焦点矩形。DrawFocusRectangle()是这方面的样板实现
但是,只有当你对键盘信息做了一些有意义的事情时,集中注意力才是真正有用的。因此,您还必须覆盖OnKeyDown和/或OnKeyPressed。并向用户显示反馈,以便用户可以看到自己键入的内容。如果你没有一个有用的实现,你就不应该关注这个问题。这就是为什么PictureBox没有
在WinForms FrameWork 3.5项目中编译
将Control1的实例从工具箱拖动到窗体表面。。。确保其TabStop属性设置为“true”
在窗体上放置一些其他控件
验证当Control1的实例被tab到时:它显示一个选择矩形,当您“tab”离开它时,该矩形消失
验证是否单击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代码
请注意,如果通过SetStyle(ControlStyles.ContainerControl,true)将上面的控件设置为“ContainerControl”;并向其添加一些其他控件,即使将添加控件的TabStop属性设置为“false:。。。如果它点击。。。它将获得焦点,您将丢失ContainerControl上显示的焦点矩形。这是不正确的。关闭UserMouse样式只应针对实现自己的鼠标消息处理的本机控件周围的控件类包装器。您允许控件获取焦点,因为您对输入事件感兴趣。故意关闭输入事件处理是没有意义的。根据您的说明,“控件自行进行鼠标处理”这句话特别令人困惑:WinForms控件是否自行进行鼠标处理(覆盖OnMouseDown
等),还是本机控件自行进行鼠标处理(意味着WinForms控件应该远离它)?无论如何,显然,UserMouse
在默认情况下是false
。而且由于我没有包装本机控件,所以它应该是true
,对吗?是的,它调用OnMouseDown方法。您可以覆盖该方法,为您自己的控件提供鼠标行为。就像给它焦点一样。您的控件继承自控件,就在这里没有包装本机Windows控件(如ListBox或TreeView)。这只是一个普通的窗口。很好,但你为什么认为我首先希望控件可以聚焦?我已经有了聚焦矩形,现在正在处理键盘处理程序。在问题中提到这些细节总是很好的。我在括号中提到它是一种列表框,这意味着它应该处理按键操作;我不想通过提及所有这些细节来分散对这个问题的注意力。但你是对的:提供关于“你为什么想要那个”的信息是很好的部分原因是,有时候你真的想用一种完全不同的方式来解决或规避潜在的问题!@Thomas:你提到“我已经有了焦点矩形”:您是通过越过OnGotFocus和OnLostFocus并调用ControlPaint.DrawFocusRectangle来实现这一点的吗?@BillW:是的,我就是这么做的。OnGotFocus
和OnLostFocus
使包含焦点矩形的矩形无效;OnPaint
检查Focused
属性并调用sControlPaint.DrawFocusRectangle
根据需要。非常感谢您的患者对我的问题的回答!我再发布一个答案,这是我在Visual Studio RC1中根据FrameWork 3.5(完整版)编译此功能的唯一方法。所谓“工作”:我的意思是,当控件“选项卡化到”:它将显示一个选择矩形,并且当“从”选项卡上移开时选择矩形消失:当单击控件时,将显示选择矩形。标记为//无效
的方法不起作用,因为您将它们声明为虚拟
,而不是覆盖
。显然用户绘制
和可选择
默认为真
。至于#6:未定义无论您是否