我正在創建一個從UserControl派生的自定義控件,我想將焦點設置爲。將焦點設置爲.NET UserControl ...?
自定義控件包含一個ComboBox控件,並在其旁邊繪製一些字符串。
ComboBox可以接收焦點,但我希望能夠將焦點設置到UserControl本身。我的OnPaint處理程序設置爲稍微不同地繪製該控件,如果它具有焦點但我創建自定義控件時返回false從父窗體調用CanFocus()。
是否有屬性或設置?
我正在創建一個從UserControl派生的自定義控件,我想將焦點設置爲。將焦點設置爲.NET UserControl ...?
自定義控件包含一個ComboBox控件,並在其旁邊繪製一些字符串。
ComboBox可以接收焦點,但我希望能夠將焦點設置到UserControl本身。我的OnPaint處理程序設置爲稍微不同地繪製該控件,如果它具有焦點但我創建自定義控件時返回false從父窗體調用CanFocus()。
是否有屬性或設置?
UserControl會打你的牙齒和指甲,以避免獲得焦點。它有自動將焦點傳遞給子控件(如果有的話)的代碼,如果它確實得到焦點。您至少必須重寫WndProc()並捕獲WM_SETFOCUS消息。可能需要其他手術,如ControlStyles.Selectable和TabStop和TabIndex屬性。
您的下一個問題是UserControl在確實有焦點時不會對鍵盤消息做出有意義的響應。您需要檢測UC背景上的點擊以處理鼠標消息,以及覆蓋該繪畫,以便用戶明白UC具有焦點(使用ControlPaint.DrawFocusRectangle)。如果這聽起來沒有吸引力,那是因爲UC真的是一個容器控制。
從http://msdn.microsoft.com/en-us/library/system.windows.forms.control.canfocus.aspx
備註
爲了控制以接收 輸入焦點時,控制必須具有 手柄分配給它,並且可見 和Enabled屬性必須既對於控制和 所有其父控件以及 控件都必須爲表格或 cont rol的最外層父項必須是 表單。
確保您符合這些prerequesits。
感謝您的回覆... 我已確認我的控件具有Handle值。該控件是可見和啓用,我也顯示它的面板是可見和啓用以及...它都出現在窗體上...! 這似乎符合先決條件... 我覆蓋OnGotFocus()並設置一個斷點,但它從來沒有被擊中。另外,我在控件的GotFocus事件的窗體對象中設置了一個處理程序,並且再次,代碼從未被擊中。 任何其他想法...? – Sambo 2010-03-02 11:42:48
這些先決條件適用於Control,但UserControl將其作爲上述@HansPassant進行破壞。 – 2014-09-23 17:01:40
太長了評論,包括鏈接和代碼...但是這是一條評論...
很多人都抱怨沒有發射了「的GotFocus()事件用戶控件。例如:UserControl and GotFocus() fyi:按照我的經驗,LostFocus()會按預期發射。在過去,在一個多表單項目中,我嘗試在每個表單的UserControl上實現「輸入和」事件處理程序,並發現「輸入只在表單加載時調用一次。
很明顯,UserControl上的控件「聚焦」(我無法解釋,但也許是SO的WinForms大師之一)。也許這與UserControl從ContainerControl降落的事實有關?
我寫一個實驗「的GotFocus()處理:
private void Control_GotFocus(object sender, EventArgs e)
{
Console.WriteLine("Control GotFocus : " + ((sender as Control).Name));
}
,然後在用戶控件」 Load事件,在用戶控件到事件處理程序連接好所有的控件:我觀察到的是, UserControl上的最低TabIndex控件會在啓動應用程序時觸發'GotFocus事件,並在Forms之間切換。
我在這種情況下提到的唯一的其他事情是確保UserControl的IsTabStop屬性設置爲True:這是在SilverLight相關問題的上下文中來自Shawn Wildermuth的,所以不知道這是否適用於你的情況。
另一個建議是爲UserControl編寫一個MouseDown或MouseClick事件處理程序,並在該調用中:使我無處可去。
希望你得到答案!
在某些情況下,也不希望焦點移動到UserControl的子元素。
在這種情況下,您還需要將ControlStyles.ContainerControl設置爲false。
Public Sub New()
InitializeComponent()
Me.SetStyle(ControlStyles.ContainerControl, False)
Me.SetStyle(ControlStyles.Selectable, True)
End Sub
說,你有你的用戶控件的圖片,你想突出它模仿「GetFocus」事件(比如專注於你的用戶控件藉此圖片)。對用戶控件的關注將通過向圖片框繪製輪廓虛線來處理。這是通過您的用戶控件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」。
這似乎是做這項工作。我會繼續玩弄它來解決你提到的錯綜複雜的問題。謝謝! – Sambo 2010-03-02 12:48:19
+1很高興能有NoBugz的另一個偉大的答案。好奇:在這種情況下,你認爲OP使用Form而不是UserControl可以做得更好嗎? – BillW 2010-03-02 14:20:26
@Bill:Form類也是一個容器控件,雖然它不會以相同的方式反擊。我的建議必須是避免非標準的UI練習。它也使用戶感到困惑。 – 2010-03-02 15:49:10