2011-08-23 196 views
4

我在WPF中有一個應用程序專門由鍵盤使用,所以我們對焦點行爲真的很挑剔。WPF焦點管理在.Net 4.0中

因此,我們在文本框中獲得了PreviewLostKeyboardFocus。在某些情況下,我們禁用接下來的5個字段,並希望焦點在此之後進入字段。有人可能會認爲焦點會做到這一點,找到下一個可調焦領域,這是如果我沒有禁用預覽事件中的字段會發生什麼。它沒有,它把重點放在第一個文本框上。

我試過用Keyboard.Focus(uielement)強制重點,但沒有任何反應。看來下一個重點目標已經提交。

我該如何做到這一點,或者我「做錯了」?我無法改變指定此行爲的要求;我知道這有些奇怪。

謝謝。

編輯:這是一個小應用程序,顯示此行爲。 XAML:

<Window x:Class="WpfApplication4.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525" 
    FocusManager.FocusedElement="{Binding ElementName=textBox0}" 
    > 
    <StackPanel> 
    <TextBox Height="23" Margin="5" Name="textBox0" Width="120" /> 
    <TextBox Height="23" Margin="5" Name="textBox1" Width="120" PreviewLostKeyboardFocus="textBox1_PreviewLostKeyboardFocus"/> 
    <TextBox Height="23" Margin="5" Name="textBox2" Width="120" /> 
    <TextBox Height="23" Margin="5" Name="textBox3" Width="120" /> 
    <TextBox Height="23" Margin="5" Name="textBox4" Width="120" /> 
    </StackPanel> 
</Window> 

代碼隱藏:

using System.Windows; 
using System.Windows.Input; 

namespace WpfApplication4 { 
    public partial class MainWindow : Window { 
     public MainWindow() { 
      InitializeComponent(); 
     } 
     private void textBox1_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { 
      textBox2.IsEnabled = false; 
      textBox3.IsEnabled = false; 
     } 
    } 
} 

一個很明顯的,值得一試(至少對我來說)是把Keyboard.focus(textBox4);PreviewLostKeyboardFocus事件處理程序。這當然沒有工作,它會導致一個循環,再次閃光的PreviewLostKeyboardFocus事件....

另一個編輯: 我發現,在textBox1_PreviewLostKeyboardFocus()使用斷點有時會導致它的行爲,或有時不甚至禁用第二個和第三個文本框。我正在考慮種族/線程問題。

+1

你沒有做錯,WPF是壞的重點管理,檢查http://joshsmithonwpf.wordpress.com/2010/03/16/control-input-focus-from-viewmodel-objects/,您可能會找到解決問題的方法。 – Matthieu

+0

有一個優雅的解決方案,將不得不明天答覆答案,因爲我現在沒有可用的代碼。在此之前... – Dennis

+1

我很高興看到你想出了什麼。謝謝。 –

回答

3

我不知道究竟是什麼原因造成這種行爲,但是從過去的經驗WPF的對焦系統是改變控件以任何方式或手動設定對焦時後極不可靠。

但是,使用分派器在WPF追上對控件的更改後執行焦點更改,通常可以解決問題。

這在我的測試中正常工作

private void textBox1_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) { 
    textBox2.IsEnabled = false; 
    textBox3.IsEnabled = false; 

    this.Dispatcher 
     .BeginInvoke(new Action(() => Keyboard.Focus(textBox4)), 
     System.Windows.Threading.DispatcherPriority.Input, null); 
} 
+0

這味道很不錯。我需要幾天的時間才能回到這個問題。我將不得不看看它是否能夠解決我們在我們項目的大範圍混亂中的問題。直到那時.... –

0

您可以通過視圖模型更好地做到這一點。您的視圖模型可以設置布爾屬性來啓用/禁用字段。我確定你不應該像這樣氾濫一個視圖模型,但它可能會使應用程序的行爲更具可預測性。我認爲wpf知道跳過禁用控件的tabstops,並且您可能能夠在選項卡中找到所需的選項卡行爲導航。