Chcę dodać proste (przynajmniej tak mi się wydawało) zachowanie do mojego WPF TextBox
.
Kiedy użytkownik naciśnie klawisz Escape, chcę TextBox
, aby edytowany przez niego tekst miał tekst, który miał, gdy użytkownik zaczął edytować, ORAZ chcę usunąć fokus z TextBox
.
Nie mam żadnego problemu z ustawieniem tekstu na wartość, którą miał na początku edycji.
Problem polega na usunięciu skupienia elementu. Nie chcę przenosić fokusu na żaden inny komponent, chcę tylko, TextBox
aby stracił fokus. Czy będę musiał mieć niewidzialny element, aby ustawić ostrość, aby moja TextBox
mogła stracić koncentrację?
Keyboard.ClearFocus()
z kodu źródłowego po kliknięciu gdzieś.ClearFocus
powoduje,GotFocus
że nie uruchamia się dla ostatnio nastawionej kontroli, podczas gdy nadal strzela do innych kontrolek. Na przykład to duży problem z moją niestandardową klawiaturą ekranową. Powoduje to zniknięcie znaku daszka, co jest prawdopodobnie wszystkim, co pociąga za sobą „fokus klawiatury”. Może bardziej interesuje mnie coś w rodzaju „skupienia myszy”.other.Focus()
.GotFocus
zdarzenie). W programie zawsze jest coś, co jest logiczne. UżyjLostKeyboardFocus
zdarzenia lub przenieś fokus na inny element (który przesuwa logiczny fokus wraz z nim) przed wyczyszczeniem fokusa klawiatury.Kod, którego używałem:
// Move to a parent that can take focus FrameworkElement parent = (FrameworkElement)textBox.Parent; while (parent != null && parent is IInputElement && !((IInputElement)parent).Focusable) { parent = (FrameworkElement)parent.Parent; } DependencyObject scope = FocusManager.GetFocusScope(textBox); FocusManager.SetFocusedElement(scope, parent as IInputElement);
źródło
Trochę za późno na imprezę, ale mi pomogło, więc proszę bardzo.
Od .Net 3.0
FrameworkElement
ma funkcję MoveFocus, która załatwiła mi sprawę .źródło
Ponieważ żadna z powyższych odpowiedzi nie zadziałała dla mnie, a zaakceptowana odpowiedź działa tylko dla fokusu klawiatury, doszedłem do następującego podejścia:
// Kill logical focus FocusManager.SetFocusedElement(FocusManager.GetFocusScope(textBox), null); // Kill keyboard focus Keyboard.ClearFocus();
Zabija zarówno logikę, jak i fokus klawiatury.
źródło
Możesz ustawić fokus na przodka, którego można fokusować. Ten kod będzie działał, nawet jeśli pole tekstowe znajduje się w szablonie bez przodków, których można fokusować w tym samym szablonie:
DependencyObject ancestor = textbox.Parent; while (ancestor != null) { var element = ancestor as UIElement; if (element != null && element.Focusable) { element.Focus(); break; } ancestor = VisualTreeHelper.GetParent(ancestor); }
źródło
ODPOWIEDŹ, całkowite usunięcie ostrości nie jest możliwe. Coś w twoim oknie zawsze będzie się skupiało.
źródło
W programowaniu na Windows Phone właśnie zrobiłem
Focus()
lubthis.Focus()
na PhoneApplicationPage i działało to jak urok.źródło
Dla mnie jest to dość trudne, szczególnie w połączeniu z wiązaniem LostFocus. Jednak moim obejściem jest dodanie pustej etykiety i skupienie się na niej.
<Label Name="ResetFocusArea" Focusable="True" FocusVisualStyle="{x:Null}" />
...
OnKeyDown(object sender, RoutedEventArgs e) { //if is Esc ResetFocusArea.Focus(); }
źródło
Moja odpowiedź nie odnosi się bezpośrednio do powyższego pytania, jednak czuję, że jego brzmienie sprawiło, że stało się ono „pytaniem” o programowe pozbycie się koncentracji. Typowy scenariusz, w którym jest to potrzebne, polega na tym, że użytkownik może wyczyścić fokus po kliknięciu lewym przyciskiem myszy tła elementu sterującego głównego, takiego jak okno.
Aby to osiągnąć, możesz utworzyć dołączone zachowanie, które przełączy fokus na dynamicznie utworzoną kontrolkę (w moim przypadku pustą etykietę). Zaleca się używanie tego zachowania na elementach najwyższego poziomu, takich jak okna, ponieważ iteruje ono po swoich elementach potomnych, aby znaleźć panel, do którego może dodać fikcyjną etykietę.
public class LoseFocusOnLeftClick : Behavior<FrameworkElement> { private readonly MouseBinding _leftClick; private readonly Label _emptyControl = new Label() { Focusable = true, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top }; public LoseFocusOnLeftClick() { _leftClick = new MouseBinding(new RelayCommand(LoseFocus), new MouseGesture(MouseAction.LeftClick)); } protected override void OnAttached() { AssociatedObject.InputBindings.Add(_leftClick); AssociatedObject.Loaded += AssociatedObject_Loaded; } protected override void OnDetaching() { AssociatedObject.InputBindings.Remove(_leftClick); AssociatedObject.Loaded -= AssociatedObject_Loaded; } private void AssociatedObject_Loaded(object sender, RoutedEventArgs e) { AssociatedObject.Loaded -= AssociatedObject_Loaded; AttachEmptyControl(); } private void AttachEmptyControl() { DependencyObject currentElement = AssociatedObject; while (!(currentElement is Panel)) { currentElement = VisualTreeHelper.GetChild(currentElement, 0); } ((Panel)currentElement).Children.Add(_emptyControl); } private void LoseFocus() { _emptyControl.Focus(); } }
źródło