在WPF中實現一個彈出層自動獲取焦點,彈出層實現是通過其UserControl的依賴屬性Visibility的綁定實現的,讓UserControl上的TextBox獲取焦點,初始實現代碼如下:
public Visibility IsVisibile { get { return (Visibility)GetValue(IsVisibileProperty); } set { SetValue(IsVisibileProperty, value); } } public static readonly DependencyProperty IsVisibileProperty = DependencyProperty.Register("IsVisibile", typeof(Visibility), typeof(WordsKeyboard), new PropertyMetadata(Visibility.Collapsed,new PropertyChangedCallback((d,e)=> { if((Visibility)e.NewValue==Visibility.Visibile) (d as MainUserControl).textBox.Focus(); })));
但是第一次彈出該層的時候焦點未在textBox上,除了第一次彈出未獲取到焦點后面的彈出都獲取到了,為了解決第一次彈出層的TextBox未獲取到焦點采用了定時器延時的方法,解決方案如下:
/// <summary> /// 定義個定時器 /// </summary> DispatcherTimer timer = new DispatcherTimer(); /// <summary> /// 構造方法 /// </summary> public MainUserContrl() { InitializeComponent(); timer.Interval = new TimeSpan(500); timer.Tick += timer_Tick; } /// <summary> /// 定時器間隔執行方法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void timer_Tick(object sender, EventArgs e) { this.MainText.Focus(); timer.Stop(); } /// <summary> /// 控制改用戶控件顯示隱藏的依賴屬性 /// </summary> public Visibility IsVisibile { get { return (Visibility)GetValue(IsVisibileProperty); } set { SetValue(IsVisibileProperty, value); } } public static readonly DependencyProperty IsVisibileProperty = DependencyProperty.Register("IsVisibile", typeof(Visibility), typeof(WordsKeyboard), new PropertyMetadata(Visibility.Collapsed,new PropertyChangedCallback((d,e)=> { if((Visibility)e.NewValue==Visibility.Collapsed) (d as WordsKeyboard).KillKeyboard(); else { (d as MainUserControl).timer.Start();//開啟定時器,讓textBox獲取到焦點 } })));
通過延時的方法就可以解決掉彈出層第一次無法獲取焦點的問題了!而后面讓textbox在能使用的情況下不能失去焦點(除非點擊彈出層的關閉按鈕,讓彈出層消失),初始實現代碼如下:
/// <summary> /// textBox失去焦點事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void textBox_LostFocus(object sender,RoutedEventArgs e) { if(textBox.IsEnabled&&!btnCancle.IsFocused) textBox.Focus(); }
上述實現,會出現死循環,假如不出現死循環btnCancle.IsFocused的值一直是false,因為取消按鈕一直沒有獲取到焦點!而解決方案實現如下:
DispatcherTimer timerLoseFocuse = new DispatcherTimer(); timerLoseFocuse.Interval = new TimeSpan(0,0,0,0,100); timerLoseFocuse.Tick+=(s,e)=> { if(CardNumArea.IsEnabled&&!BtnCancel.IsFocused) { this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render,new Action(()=> { t.extBox.Focus(); }));//改方法能解決掉LoseFocuse出現死循環的問題 } timerLoseFocuse.Stop(); }; /// <summary> ///失去焦點事件 /// </summary> private void textBox_LostFocus(object sender, RoutedEventArgs e) { timerLoseFocuse.Start(); }
通過定時器解決取消按鈕無法獲取到獲取到焦點的問題,否則點擊取消無法執行其點擊事件