Anda dapat menjadikan diri Anda sendiri pendekatan XAML murni dengan membuat perilaku terlampir .
Sesuatu seperti ini:
public static class InputBindingsManager
{
public static readonly DependencyProperty UpdatePropertySourceWhenEnterPressedProperty = DependencyProperty.RegisterAttached(
"UpdatePropertySourceWhenEnterPressed", typeof(DependencyProperty), typeof(InputBindingsManager), new PropertyMetadata(null, OnUpdatePropertySourceWhenEnterPressedPropertyChanged));
static InputBindingsManager()
{
}
public static void SetUpdatePropertySourceWhenEnterPressed(DependencyObject dp, DependencyProperty value)
{
dp.SetValue(UpdatePropertySourceWhenEnterPressedProperty, value);
}
public static DependencyProperty GetUpdatePropertySourceWhenEnterPressed(DependencyObject dp)
{
return (DependencyProperty)dp.GetValue(UpdatePropertySourceWhenEnterPressedProperty);
}
private static void OnUpdatePropertySourceWhenEnterPressedPropertyChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
{
UIElement element = dp as UIElement;
if (element == null)
{
return;
}
if (e.OldValue != null)
{
element.PreviewKeyDown -= HandlePreviewKeyDown;
}
if (e.NewValue != null)
{
element.PreviewKeyDown += new KeyEventHandler(HandlePreviewKeyDown);
}
}
static void HandlePreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
DoUpdateSource(e.Source);
}
}
static void DoUpdateSource(object source)
{
DependencyProperty property =
GetUpdatePropertySourceWhenEnterPressed(source as DependencyObject);
if (property == null)
{
return;
}
UIElement elt = source as UIElement;
if (elt == null)
{
return;
}
BindingExpression binding = BindingOperations.GetBindingExpression(elt, property);
if (binding != null)
{
binding.UpdateSource();
}
}
}
Kemudian di XAML Anda, Anda mengatur InputBindingsManager.UpdatePropertySourceWhenEnterPressedProperty
properti ke properti yang ingin Anda perbarui ketika Entertombol ditekan. Seperti ini
<TextBox Name="itemNameTextBox"
Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}"
b:InputBindingsManager.UpdatePropertySourceWhenEnterPressed="TextBox.Text"/>
(Anda hanya perlu memastikan untuk menyertakan referensi xmlns clr-namespace untuk "b" di elemen root dari file XAML Anda yang menunjuk ke namespace mana Anda meletakkan InputBindingsManager di dalamnya).
UpdatePropertySourceWhenEnterPressed
perubahan dari nilai valid ke nilai valid berbeda, Anda berhenti berlangganan & berlangganan kembaliPreviewKeyDown
acara jika tidak perlu. Sebaliknya, yang Anda perlukan hanyalah memeriksa apakahe.NewValue
adanull
atau tidak. Jika tidaknull
, maka berlangganan; jika tidak,null
maka berhenti berlangganan.Beginilah cara saya memecahkan masalah ini. Saya membuat penangan acara khusus yang masuk ke kode di belakang:
Lalu saya baru saja menambahkan ini sebagai pengendali acara KeyUp di XAML:
Penangan kejadian menggunakan
sender
referensinya agar pengikatannya sendiri diperbarui. Karena event handler berdiri sendiri maka itu harus bekerja dalam DataTemplate yang kompleks. Penangan kejadian yang satu ini sekarang dapat ditambahkan ke semua kotak teks yang membutuhkan fitur ini.sumber
KeyBinding
XAML untuk mengaktifkan metode ini karena UI saya memiliki kontrol "Default" yang menangkap tombol enter. Anda harus menangkapnya di dalam TextBox ini untuk menghentikannya menyebarkan pohon UI ke kontrol "Default".Saya tidak percaya bahwa ada cara "XAML murni" untuk melakukan apa yang Anda gambarkan. Anda bisa menyiapkan pengikatan agar diperbarui setiap kali teks dalam TextBox berubah (bukan saat TextBox kehilangan fokus) dengan menyetel properti UpdateSourceTrigger , seperti ini:
Jika Anda menyetel UpdateSourceTrigger ke "Explicit" dan kemudian menangani event PreviewKeyDown dari TextBox (mencari tombol Enter) maka Anda dapat mencapai apa yang Anda inginkan, tetapi akan membutuhkan kode di belakang. Mungkin semacam properti terlampir (mirip dengan properti EnterKeyTraversal saya ) akan bekerja untuk Anda.
sumber
Anda dapat dengan mudah membuat kontrol Anda sendiri yang diwarisi dari TextBox dan menggunakannya kembali di seluruh proyek Anda.
Sesuatu yang mirip dengan ini seharusnya berfungsi:
Mungkin ada cara untuk menyiasati langkah ini, tetapi sebaliknya Anda harus mengikat seperti ini (menggunakan Eksplisit):
sumber
Jika Anda menggabungkan solusi Ben dan ausadmin, Anda akan mendapatkan solusi yang sangat ramah MVVM:
... yang berarti Anda meneruskan
TextBox
dirinya sebagai parameter keCommand
.Ini mengarah pada
Command
tampilan Anda seperti ini (jika Anda menggunakanDelegateCommand
implementasi -style di VM Anda):Command
Implementasi ini dapat digunakan untuk semuaTextBox
dan yang terbaik dari semua tanpa kode di belakang kode meskipun Anda mungkin ingin meletakkan ini di kelasnya sendiri sehingga tidak ada ketergantungan padaSystem.Windows.Controls
VM Anda. Itu tergantung pada seberapa ketat pedoman kode Anda.sumber
Berikut adalah pendekatan yang bagi saya tampaknya cukup mudah, dan lebih mudah daripada menambahkan AttachedBehaviour (yang juga merupakan solusi yang valid). Kami menggunakan UpdateSourceTrigger default (LostFocus for TextBox), dan kemudian menambahkan InputBinding ke Enter Key, terikat ke perintah.
Xaml adalah sebagai berikut
Kemudian metode Command adalah
Dan TextBox terikat ke Properti
Sejauh ini tampaknya berfungsi dengan baik dan menangkap acara Enter Key di TextBox.
sumber
Ini bukan jawaban untuk pertanyaan awal, melainkan perpanjangan dari jawaban yang diterima oleh @Samuel Jack. Saya melakukan hal berikut dalam aplikasi saya sendiri, dan kagum dengan keanggunan solusi Samuel. Ini sangat bersih, dan sangat dapat digunakan kembali, karena dapat digunakan pada kontrol apa pun, bukan hanya
TextBox
. Saya pikir ini harus dibagikan dengan komunitas.Jika Anda memiliki Jendela dengan seribu
TextBoxes
yang semuanya perlu memperbarui Sumber Binding pada Enter, Anda dapat melampirkan perilaku ini ke semuanya dengan memasukkan XAML di bawah ini ke dalam AndaWindow
Resources
daripada melampirkannya ke setiap Kotak Teks. Pertama, Anda harus menerapkan perilaku terlampir sesuai posting Samuel , tentu saja.Anda selalu dapat membatasi cakupan, jika perlu, dengan meletakkan Style ke dalam Sumber daya salah satu elemen anak Window (yaitu a
Grid
) yang berisi TextBoxes target.sumber
Jika Anda menggunakan MultiBinding dengan TextBox Anda, Anda perlu menggunakan
BindingOperations.GetMultiBindingExpression
metode alih-alihBindingOperations.GetBindingExpression
.sumber
Ini bekerja untuk saya:
sumber
Menjawab di sini dengan cukup elegan menggunakan perilaku terlampir, metode yang saya sukai untuk hampir semua hal.
WPF cara membuat kotak teks kehilangan fokus setelah menekan enter
sumber
Menurut saya pribadi, memiliki Ekstensi Markup adalah pendekatan yang lebih bersih.
sumber
Solusi lain (tidak menggunakan xaml tapi masih cukup bersih menurut saya).
sumber