Csharp/C#教程:将焦点设置为.NET UserControl ……?分享


将焦点设置为.NET UserControl ……?

我正在创建一个从UserControl派生的自定义控件,我想将焦点设置为。

自定义控件包含一个ComboBox控件,我在它旁边绘制一些字符串。

ComboBox可以获得焦点,但我希望能够将焦点设置为UserControl本身。 如果它具有焦点,我的OnPaint处理程序设置为稍微不同地绘制控件,但是当我创建自定义控件时它从父窗体调用CanFocus()并返回false。

是否有财产或其他东西?

UserControl将为你而战,以避免获得焦点。 它具有自动将焦点传递给子控件(如果有)的代码,如果它确实获得焦点。 您至少必须覆盖WndProc()并捕获WM_SETFOCUS消息。 可能还需要其他手术,例如ControlStyles.Selectable以及TabStop和TabIndex属性。

您的下一个问题是,当UserControl确实具有焦点时,它不会对键盘消息做出有意义的响应。 您需要检测UC背景上的点击以处理鼠标消息,并覆盖绘画,以便用户明白UC具有焦点(使用ControlPaint.DrawFocusRectangle)。 如果这开始听起来没有吸引力,那是因为UC真的是一个集装箱控制。

来自https://msdn.microsoft.com/en-us/library/system.windows.forms.control.canfocus.aspx

备注

为了使控件能够接收输入焦点,控件必须为其分配一个句柄,并且对于控件及其所有父控件,Visible和Enabled属性都必须都设置为true,并且控件必须是一个表单或控件的最外层父级必须是一个表单。

确保您已满足这些先决条件。

评论太长,包括链接和代码……但这是评论……

很多人抱怨UserControl没有触发’GotFocus()事件。 例如:根据我的经验, UserControl和GotFocus() fyi:LostFocus()将按预期触发。 过去,在一个多表单项目中,我已尝试在每个表单上的UserControl上实现’Enter和’Leave事件处理程序,并发现’Enter仅在表单加载时调用一次。

显然,UserControl上的控件“需要关注”(我无法解释,但也许是SO的WinForms专家之一)。 也许这与UserControl来自ContainerControl的事实有关?

我尝试编写一个’GotFocus()处理程序:

private void Control_GotFocus(object sender, EventArgs e) { Console.WriteLine("Control GotFocus : " + ((sender as Control).Name)); } 

然后,在UserControl的Load事件中,将UserControl上的所有控件连接到该事件处理程序:我观察到的是具有最低TabIndex的UserControl上的Control将在启动应用程序时触发’GotFocus事件,并且在表格之间切换。

我在这种情况下提到的唯一另一件事就是确保UserControl的’IsTabStop属性设置为’True:这是来自Silver的Shawn Wildermuth在SilverLight相关问题的上下文中,所以不知道这是不是可能适用于您的情况。

另一个建议是为UserControl写一个MouseDown或MouseClick事件处理程序,并在该调用中: this.SetFocus(); 让我无处可去。

希望你能得到答案!

在某些情况下,还希望不让焦点移动到UserControl的子元素。
在这种情况下,您还需要将ControlStyles.ContainerControl设置为false。

 Public Sub New() InitializeComponent() Me.SetStyle(ControlStyles.ContainerControl, False) Me.SetStyle(ControlStyles.Selectable, True) End Sub 

比如,你的用户控件上有一张图片,你想要突出显示它模仿“GetFocus”事件(比如专注于你的用户控件就会拍下这张照片)。 将通过向PictureBox绘制轮廓虚线来处理对用户控件的关注。 这是通过用户控件OnEnter和OnLeave事件完成的。 这是突出的程序……

 Public Sub highlightImage() Dim l As Single() = {2, 2, 2, 2} Dim p As New Pen(Color.Gray, 1) p.DashPattern = l Dim g As Graphics = picColor.CreateGraphics() g.DrawRectangle(p, 0, 0, picColor.Width - 1, picColor.Height - 1) End Sub 

这两个覆盖将完成这项工作。

 Protected Overrides Sub OnEnter(e As EventArgs) MyBase.OnEnter(e) Me.highlightImage() End Sub Protected Overrides Sub OnLeave(e As EventArgs) MyBase.OnLeave(e) MyBase.Refresh() End Sub 

如果UserControl获得焦点,它会在内部将焦点传递给其子控件。

因此,您需要跳过执行将焦点设置为子控件的代码。 为此,您需要覆盖WndProc()跳过执行任何WM_SETFOCUS消息。

  public class FocusableUserControl : UserControl { protected override void WndProc(ref Message m) { switch (m.Msg) { case (int)Win32Constants.WM_SETFOCUS: //Returning from here will skip setting focus to child controls. //It will not skip setting focus to this control. Console.WriteLine("FocusableUserControl is focused: " + Focused); return; } base.WndProc(ref m); } } 

其中WM_SETFOCUS是“0x0007”。

上述就是C#学习教程:将焦点设置为.NET UserControl ……?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1001923.html

(0)
上一篇 2021年12月27日
下一篇 2021年12月27日

精彩推荐