Saya ingin menambahkan perilaku sederhana (setidaknya saya pikir itu) ke WPF saya TextBox
.
Ketika pengguna menekan Escape, saya ingin TextBox
dia yang sedang mengedit memiliki teks yang dimilikinya saat pengguna mulai mengedit, DAN saya ingin menghapus fokus dari TextBox
.
Saya tidak memiliki masalah dalam menyetel teks untuk nilai yang dimilikinya di awal pengeditan.
Masalahnya adalah menghilangkan fokus elemen. Saya tidak ingin memindahkan fokus ke komponen lain, saya hanya ingin TextBox
kehilangan fokus. Apakah saya harus memiliki elemen tak terlihat untuk mengatur fokus sehingga saya TextBox
bisa kehilangan fokus?
Keyboard.ClearFocus()
dari belakang kode setelah klik di suatu tempat.ClearFocus
penyebabGotFocus
tidak aktifnya kontrol yang difokuskan baru-baru ini saat masih aktif untuk kontrol lain. Itu masalah besar untuk keyboard layar kustom saya, misalnya. Itu memang menyebabkan tanda sisipan menghilang, yang mungkin merupakan semua yang diperlukan "fokus keyboard". Mungkin saya lebih tertarik pada sesuatu seperti "fokus mouse".other.Focus()
.GotFocus
acara). Selalu ada sesuatu dengan fokus logis dalam program Anda. GunakanLostKeyboardFocus
peristiwa atau alihkan fokus ke elemen lain (yang menggeser fokus logis bersamanya) sebelum menghapus fokus keyboard.Kode yang telah saya gunakan:
// 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);
sumber
Agak terlambat ke pesta, tapi itu membantu saya jadi ini dia.
Sejak .Net 3.0,
FrameworkElement
memiliki fungsi MoveFocus yang melakukan trik untuk saya.sumber
Karena tidak ada jawaban di atas yang berhasil untuk saya dan jawaban yang diterima hanya berfungsi untuk fokus keyboard, saya sampai pada pendekatan berikut:
// Kill logical focus FocusManager.SetFocusedElement(FocusManager.GetFocusScope(textBox), null); // Kill keyboard focus Keyboard.ClearFocus();
Membunuh keduanya, logis serta fokus keyboard.
sumber
Anda bisa mengatur fokus ke leluhur yang bisa difokuskan. Kode ini akan berfungsi bahkan jika kotak teks berada di dalam templat tanpa leluhur yang dapat difokuskan di dalam templat yang sama:
DependencyObject ancestor = textbox.Parent; while (ancestor != null) { var element = ancestor as UIElement; if (element != null && element.Focusable) { element.Focus(); break; } ancestor = VisualTreeHelper.GetParent(ancestor); }
sumber
AFAIK, tidak mungkin menghapus fokus sepenuhnya. Sesuatu di Jendela Anda akan selalu menjadi fokus.
sumber
Dalam Pengembangan Windows Phone, saya baru saja melakukannya
Focus()
atauthis.Focus()
di PhoneApplicationPage dan bekerja seperti pesona.sumber
Bagi saya, ini cukup rumit, terutama saat menggunakan dengan pengikatan LostFocus. Namun, solusi saya adalah menambahkan label kosong dan fokus padanya.
<Label Name="ResetFocusArea" Focusable="True" FocusVisualStyle="{x:Null}" />
...
OnKeyDown(object sender, RoutedEventArgs e) { //if is Esc ResetFocusArea.Focus(); }
sumber
Jawaban saya tidak menjawab pertanyaan di atas secara langsung, namun saya merasa bahwa pengkalimatannya telah menyebabkannya menjadi "Pertanyaan" tentang menghilangkan fokus secara terprogram. Skenario umum yang memerlukan ini adalah agar pengguna dapat menghapus fokus setelah mengklik kiri latar belakang kontrol root, seperti jendela.
Jadi, untuk mencapai ini, Anda dapat membuat Attached Behavior yang akan mengalihkan fokus ke kontrol yang dibuat secara dinamis (dalam kasus saya, label kosong). Lebih disukai untuk menggunakan perilaku ini pada elemen tingkat tertinggi seperti jendela, karena ia melakukan iterasi melalui turunannya untuk menemukan panel yang dapat ditambahkan label tiruan.
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(); } }
sumber