2010-01-12 17 views
32

Mam TextBox i ToolBar z Button. Jeśli piszę w numerze TextBox i klikam na Button chcę, aby TextBox stracił Focus, aby powiązanie zostało zaktualizowane. Nie chcę dodawać UpdateSourceTrigger=PropertyChanged do mojego TextBox. Ale zamiast tego po kliknięciu na resetuję Focus do głównego okna, więc to, czym jestem, traci Focus i aktualizuje wiązania.WPF Resetuj fokus na przycisku Kliknij

Próbowałem dodanie OnClick przycisku z następujących, ale nie wydaje się działać:

private void Button_Click(object sender, RoutedEventArgs e) { 
     FocusManager.SetFocusedElement(this, null); 
    } 

Wszelkie wskazówki będą mile widziane.

Dzięki, Raul

Odpowiedz

25

Problem polega na tym, że pasek narzędzi umieszcza swój przycisk w innym FocusManager.FocusScope. Oznacza to, że zarówno Button, jak i TextBox mogą odbierać logiczne ogniskowanie w tym samym czasie, każde w swoim własnym zakresie. Zazwyczaj jest to dobre rozwiązanie, ponieważ zazwyczaj nie chcesz tracić fokusu w głównym obszarze okna, gdy wybierasz pozycje menu i przyciski paska narzędziowego, ale w twoim przypadku uniemożliwia to działanie.

Mimo że można zastąpić właściwość FocusManager.IsFocusScope na pasku narzędzi i uzyskać pożądany efekt, prawdopodobnie nie jest to najlepszy plan, ponieważ spowoduje to, że wszystkie pozostałe przyciski paska narzędzi również wykrają fokus z obszaru głównego okna.

Zamiast tego można skorzystać z jednej z kilku prostych rozwiązań:

  • Umieść przycisk poza Toolbar
  • Dodaj aktywowana = „true” sterowanie do głównego obszaru okna i skupić ją po kliknięciu przycisku
  • ręcznie wymusić aktualizację poprzez wywołanie textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource()
  • Tymczasowo ustaw ponownie = „true” na kontroli w oknie głównym, ustaw ostrość na nią, a następnie niezwłocznie Regulowana = „false” Regulowana
+0

Próbowałem Keyboard.Focus (mainWindow); ale to też nie zmienia ostrości. Pozostaje on w polu tekstowym lub kiedykolwiek został wybrany element. Na razie po prostu wyraźnie wymuszam ten element na UpdateSource(), ale nie wydaje mi się to długoterminowym, zrównoważonym rozwiązaniem. Spróbuję dodać kontrolę ducha, aby ustawić ostrość na. – HaxElit

+1

'Keyboard.Focus (mainWindow)' będzie działał tylko wtedy, gdy "mainWindow" jest ustawialny (domyślnie nie jest) i jeśli jest w tym samym 'FocusScope' jako' TextBox'. Spróbuj utworzyć kontrolkę 'Focusable =" true "' w tym samym kontenerze co TextBox i skup się na tym. Drugą kontrolką może być proste "'. Ponieważ 'Control' nie ma domyślnego szablonu, będzie niewidoczny. –

+0

Awesome! To działało jak czar. Dzięki! – HaxElit

32

Napotkałem podobny problem. Potrzebuję nieostrości pola tekstowego po naciśnięciu klawisza Enter. Kończę z tym kodem:

var scope = FocusManager.GetFocusScope(elem); // elem is the UIElement to unfocus 
FocusManager.SetFocusedElement(scope, null); // remove logical focus 
Keyboard.ClearFocus(); // remove keyboard focus 

Wydaje mi się, że jest czystszy niż tworzenie kontrolek obojętnych i jest wielokrotnego użytku. Nie jestem jednak pewien tego rozwiązania. Ale wygląda na to, że działa dobrze.

+3

+1 Działa jak czar w kontrolkach GotFocus() Event. –

+3

To działało dla mnie, gdy nic innego nie zmusiłoby DatePicker do parsowania wprowadzonego tekstu po kliknięciu przycisku zapisu na pasku narzędzi. Poniższy kod wykorzystuje widok (MVVM) jako plik ten.owner, wywoływany z ViewModel. var t = (DependencyObject) FocusManager.GetFocusedElement (this.Owner); var scope = FocusManager.GetFocusScope (t); FocusManager.SetFocusedElement (scope, null); – Dave