Bagaimana cara memilih semua teks pada fokus secara otomatis di WPF TextBox?

232

Jika saya menelepon SelectAlldari GotFocuspengendali acara, itu tidak berfungsi dengan mouse - pilihan menghilang segera setelah mouse dilepaskan.

EDIT: Orang-orang menyukai jawaban Donnelle, saya akan mencoba menjelaskan mengapa saya tidak menyukainya sebanyak jawaban yang diterima.

  • Itu lebih kompleks, sementara jawaban yang diterima melakukan hal yang sama dengan cara yang lebih sederhana.
  • Kegunaan jawaban yang diterima lebih baik. Ketika Anda mengklik di tengah teks, teks menjadi tidak dipilih ketika Anda melepaskan mouse yang memungkinkan Anda untuk mulai mengedit secara instan, dan jika Anda masih ingin memilih semua, cukup tekan tombol lagi dan kali ini tidak akan membatalkan pilihan pada rilis. Mengikuti resep Donelle, jika saya mengklik di tengah teks, saya harus mengklik kedua kalinya untuk dapat mengedit. Jika saya mengklik di suatu tempat di dalam teks versus di luar teks, ini kemungkinan besar berarti saya ingin mulai mengedit alih-alih menimpa segalanya.
Sergey Aldoukhov
sumber
Jika Anda akan memiliki lebih dari satu formulir, jawabannya tetap menjadi kurang kompleks daripada yang pertama. Kegunaan kedua opsi dapat diperdebatkan karena Anda dapat mengubah cara keduanya bekerja.
halaman
1
@Sergey: Anda mungkin ingin mengubah jawaban yang diterima untuk pertanyaan ini, karena sudah ada jawaban yang lebih baik sejak itu. Saya tidak akan menyarankan milik saya, tetapi Anda bisa;)
Grokys
Pertanyaan memiliki tag Silverlight, namun Silverlight tidak memiliki sebagian besar acara / jenis acara pratinjau sama sekali. Solusi mana yang harus digunakan untuk cahaya perak?
Valentin Kuzub
Tautan "Mengapa fokus di WPF begitu rumit?" rusak
Maxence
1
seperti yang disebutkan dalam komentar di stackoverflow.com/a/2553297/492 di bawah ini, madprops.org/blog/wpf-textbox-selectall-on-focus adalah solusi mudah dan menjaga perilaku nouse asli. Saya meletakkan pendaftaran acara di konstruktor karena saya hanya memiliki satu kontrol WPF di aplikasi.
CAD berbicara

Jawaban:

75

Tidak tahu mengapa itu kehilangan pilihan dalam GotFocusacara tersebut.

Tapi salah satu solusinya adalah dengan melakukan seleksi pada GotKeyboardFocusdan GotMouseCaptureacara. Dengan begitu itu akan selalu berhasil.

gcores
sumber
10
Nggak. Ketika diklik dengan mouse di tengah teks yang ada - pilihan hilang segera setelah tombol mouse dilepaskan.
Sergey Aldoukhov
3
Meskipun - setelah satu klik kedua, itu akan memilih semua teks lagi ... Tidak yakin apakah itu perilaku yang dimaksudkan dari desainer WPF, tetapi kegunaannya tidak terlalu buruk. Perbedaan lain dari penangan GotFocus tunggal adalah bahwa mengklik ruang kosong di TextBox tidak memilih semua.
Sergey Aldoukhov
3
Ini juga solusi pertama saya. Tetapi saya menemukan bahwa pengguna benar-benar kesal, ketika mereka tidak dapat memilih Teks menggunakan Mouse, karena setiap kali mereka mengklik seluruh teks akan dipilih ...
Nils
1
Salah satu kelemahan lebih lanjut dari solusi ini adalah ketika Anda menggunakan menu "Cut / Copy / Paste" dari TextBox, seluruh teks dipilih ketika Anda memilih item menu.
@cores Saya tahu ini sudah tua, tetapi apakah ada yang tahu mengapa di acara GotFocus teks yang dipilih hilang? Anda benar tentang itu bekerja di acara lain, dan itu solusi yang bisa diterima dalam buku saya.
Feign
210

Kami memilikinya sehingga klik pertama memilih semua, dan klik lain menuju kursor (aplikasi kami dirancang untuk digunakan pada tablet dengan pena).

Anda mungkin menemukan itu berguna.

public class ClickSelectTextBox : TextBox
{
    public ClickSelectTextBox()
    {
        AddHandler(PreviewMouseLeftButtonDownEvent, 
          new MouseButtonEventHandler(SelectivelyIgnoreMouseButton), true);
        AddHandler(GotKeyboardFocusEvent, 
          new RoutedEventHandler(SelectAllText), true);
        AddHandler(MouseDoubleClickEvent, 
          new RoutedEventHandler(SelectAllText), true);
    }

    private static void SelectivelyIgnoreMouseButton(object sender, 
                                                     MouseButtonEventArgs e)
    {
        // Find the TextBox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        if (parent != null)
        {
            var textBox = (TextBox)parent;
            if (!textBox.IsKeyboardFocusWithin)
            {
                // If the text box is not yet focussed, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
        }
    }

    private static void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }
}
Donnelle
sumber
9
Terima kasih banyak untuk ini. Ini bekerja dengan sangat baik dan seharusnya menjadi jawaban yang diterima IMHO. Kode di atas berfungsi ketika TextBox menerima fokus melalui keyboard atau mouse (dan tampaknya stylus). +1
Drew Noakes
5
Saya melihat jawaban yang hampir identik di sini social.msdn.microsoft.com/Forums/en-US/wpf/thread/… , ia berfungsi juga, bagaimana pun ia tidak menggunakan e.OriginalSource, atau merangkak melalui pohon visual. Apakah ada keuntungan melakukan semua ini?
Marco Luglio
1
Berfungsi bagus, tetapi akan sempurna jika masih memungkinkan pemilihan teks dengan mouse. Bilah alamat Google Chrome adalah contoh sempurna dari sistem yang ideal: jika pengguna mengklik dan melepaskan tanpa menyeret, seluruh teks disorot. Namun jika pengguna mengklik dan menyeret, seret memilih teks secara normal tanpa memilih semua. SelectAll hanya terjadi pada rilis mouse . Saya akan mengutak-atik dan melihat apakah saya dapat memperbaiki desain ini sama sekali.
devios1
2
Salah satu kelemahan lebih lanjut dari solusi ini adalah ketika Anda menggunakan menu "Cut / Copy / Paste" dari TextBox, seluruh teks dipilih ketika Anda memilih item menu.
1
Saya menemukan bahwa tes tambahan dalam SelectAllTextmetode textBox.IsFocusedmemperbaikinya. Anda tidak ingin memilih semua ketika GetKeyboardFocusitu karena alt-tab ke dalam program.
Scott Stafford
164

Jawaban Donnelle bekerja dengan baik, tetapi harus mendapatkan kelas baru untuk menggunakannya adalah menyakitkan.

Alih-alih melakukan itu, saya mendaftarkan handler handler di App.xaml.cs untuk semua TextBox dalam aplikasi. Ini memungkinkan saya untuk menggunakan jawaban Donnelle dengan kontrol TextBox standar.

Tambahkan metode berikut ke App.xaml.cs Anda:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e) 
    {
        // Select the text in a TextBox when it receives focus.
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseLeftButtonDownEvent,
            new MouseButtonEventHandler(SelectivelyIgnoreMouseButton));
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotKeyboardFocusEvent, 
            new RoutedEventHandler(SelectAllText));
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.MouseDoubleClickEvent,
            new RoutedEventHandler(SelectAllText));
        base.OnStartup(e); 
    }

    void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
        // Find the TextBox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        if (parent != null)
        {
            var textBox = (TextBox)parent;
            if (!textBox.IsKeyboardFocusWithin)
            {
                // If the text box is not yet focused, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
        }
    }

    void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }
}
Grokys
sumber
4
Ini adalah solusi yang cukup keren, itu juga dijelaskan oleh Matt Hamilton berabad-abad yang lalu di sini: madprops.org/blog/wpf-textbox-selectall-on-focus
Ashley Davis
Ada yang salah eja dalam 'terima', 'fokus'
Nate Zaugg
2
Terima kasih Nate, dikoreksi, meskipun dalam pembelaan saya, saya ingin menunjukkan kesalahan pengejaan disalin kata demi kata dari jawaban Donnelle;)
Grokys
Pertanyaan memiliki tag Silverlight, namun Silverlight tidak memiliki sebagian besar acara / jenis acara pratinjau sama sekali. Solusi mana yang harus digunakan untuk cahaya perak? terima kasih sebelumnya
Valentin Kuzub
4
"Ejaan yang difokuskan jauh lebih umum di AS; namun, ejaan yang difokuskan kadang-kadang digunakan di Inggris dan Kanada, dan khususnya umum di Australia dan Selandia Baru." Jadi nyah;)
Donnelle
85

Ini agak lama, tetapi saya tetap akan menampilkan jawaban saya.

Saya telah memilih sebagian dari jawaban Donnelle (melewatkan klik dua kali) karena saya pikir ini lebih alami. Namun, seperti gcores saya tidak suka kebutuhan untuk membuat kelas turunan. Tapi saya juga tidak suka gcoresOnStartup metode . Dan saya membutuhkan ini atas dasar "umumnya tetapi tidak selalu".

Saya telah mengimplementasikan ini sebagai lampiran DependencyPropertysehingga saya dapat mengatur local:SelectTextOnFocus.Active = "True"xaml. Saya menemukan cara ini yang paling menyenangkan.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

public class SelectTextOnFocus : DependencyObject
{
    public static readonly DependencyProperty ActiveProperty = DependencyProperty.RegisterAttached(
        "Active",
        typeof(bool),
        typeof(SelectTextOnFocus),
        new PropertyMetadata(false, ActivePropertyChanged));

    private static void ActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is TextBox)
        {
            TextBox textBox = d as TextBox;
            if ((e.NewValue as bool?).GetValueOrDefault(false))
            {
                textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
            }
            else
            {
                textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
            }
        }
    }

    private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DependencyObject dependencyObject = GetParentFromVisualTree(e.OriginalSource);

        if (dependencyObject == null)
        {
            return;
        }

        var textBox = (TextBox)dependencyObject;
        if (!textBox.IsKeyboardFocusWithin)
        {
            textBox.Focus();
            e.Handled = true;
        }
    }

    private static DependencyObject GetParentFromVisualTree(object source)
    {
        DependencyObject parent = source as UIElement;
        while (parent != null && !(parent is TextBox))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }

        return parent;
    }

    private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
    {
        TextBox textBox = e.OriginalSource as TextBox;
        if (textBox != null)
        {
            textBox.SelectAll();
        }
    }

    [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static bool GetActive(DependencyObject @object)
    {
        return (bool) @object.GetValue(ActiveProperty);
    }

    public static void SetActive(DependencyObject @object, bool value)
    {
        @object.SetValue(ActiveProperty, value);
    }
}

Untuk fitur "umum tapi tidak selalu", saya mengatur Atribut Properti ini Truemenjadi (global) TextBox Style. Dengan cara ini "memilih Teks" selalu "aktif", tetapi saya dapat menonaktifkannya berdasarkan per-kotak teks.

Nils
sumber
8
+1 ini jauh lebih baik daripada mengaturnya secara global, dan ini lebih 'cara WPF' daripada berasal dari TextBox.
stijn
3
+1 Setuju dengan stijn. "Menyembunyikan" kode Anda di app.cs tidak baik untuk pengembang miskin yang harus mencari tahu mengapa SelectAllOnFocus terjadi. :-) Saya baru saja menjatuhkan ini ke kelas saya untuk TextBoxBehaviors dan kemudian memperbarui Gaya TextBox dasar saya. Berhasil memperlakukan. Cheers
Lee Campbell
2
@tronda: Cukup tambahkan gaya ke sumber daya menggunakan TargetType dari TextBox. Saya sarankan Anda melihat di wpftutorial.net/Styles.html
Nils
2
+1 lainnya untuk jawaban terbaik. Satu-satunya masalah yang saya temukan adalah bahwa teks selalu dipilih bahkan ketika saya menggunakan tombol kanan mouse - yang sering saya lakukan untuk mengedit teks melalui menu konteks - solusinya tidak berfungsi untuk kasus ini karena selalu memilih semua teks bahkan jika saya hanya ingin memotong 1 kata melalui menu konteks. Apakah kalian tahu cara memperbaikinya?
user3313608
2
Saya suka jawaban ini tetapi mengapa Anda harus memperpanjang DependencyObject? Saya menghapusnya dan masih berfungsi dengan baik.
Fred
47

Berikut adalah perilaku Blend yang menerapkan solusi jawaban untuk kenyamanan Anda:

Satu untuk melampirkan ke TextBox tunggal:

public class SelectAllTextOnFocusBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotKeyboardFocus += AssociatedObjectGotKeyboardFocus;
        AssociatedObject.GotMouseCapture += AssociatedObjectGotMouseCapture;
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObjectPreviewMouseLeftButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.GotKeyboardFocus -= AssociatedObjectGotKeyboardFocus;
        AssociatedObject.GotMouseCapture -= AssociatedObjectGotMouseCapture;
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObjectPreviewMouseLeftButtonDown;
    }

    private void AssociatedObjectGotKeyboardFocus(object sender,
        System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        AssociatedObject.SelectAll();
    }

    private void AssociatedObjectGotMouseCapture(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        AssociatedObject.SelectAll();   
    }

    private void AssociatedObjectPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if(!AssociatedObject.IsKeyboardFocusWithin)
        {
            AssociatedObject.Focus();
            e.Handled = true;
        }
    }
}

Dan satu untuk melampirkan ke akar wadah yang berisi beberapa TextBox'es:

public class SelectAllTextOnFocusMultiBehavior : Behavior<UIElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotKeyboardFocus += HandleKeyboardFocus;
        AssociatedObject.GotMouseCapture += HandleMouseCapture;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.GotKeyboardFocus -= HandleKeyboardFocus;
        AssociatedObject.GotMouseCapture -= HandleMouseCapture;
    }

    private static void HandleKeyboardFocus(object sender,
        System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        var txt = e.NewFocus as TextBox;
        if (txt != null)
            txt.SelectAll();
    }

    private static void HandleMouseCapture(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        var txt = e.OriginalSource as TextBox;
        if (txt != null)
            txt.SelectAll();
    }
}
Sergey Aldoukhov
sumber
Sejauh ini, ini adalah solusi terbaik dan terbersih. Terima kasih banyak telah membagikannya.
Golvellius
Ini terlihat sangat bagus, tetapi karena beberapa alasan itu merusak kontrol tab ... Ada yang tahu kenapa?
Marc
Saya ingin menggunakan solusi Anda. Tapi benar-benar hilang ... mungkin Anda punya sampel?
Juan Pablo Gomez
Ketika Anda mengklik di suatu tempat di kotak teks sambil memiliki fokus (bayangkan Anda ingin memindahkan tanda sisipan ke tempat lain) itu akan SelectAll lagi alih-alih memindahkan tanda tanda. Itu tidak terduga. Memperbaikinya dengan mengganti GotMouseCapture dengan MouseDoubleClick yang umum. Berkat solusi terakhir dari MSDN.
norekhov
1
Tampaknya tidak berfungsi ketika kotak teks menerima fokus awal melalui FocusManager.FocusedElement. Ada ide kenapa?
szx
24

Meskipun ini adalah pertanyaan lama, saya baru saja mengalami masalah ini tetapi menyelesaikannya menggunakan Perilaku Terlampir, bukan Perilaku Ekspresi seperti dalam jawaban Sergey. Ini berarti saya tidak memerlukan dependensi di System.Windows.Interactivitydalam Blend SDK:

public class TextBoxBehavior
{
    public static bool GetSelectAllTextOnFocus(TextBox textBox)
    {
        return (bool)textBox.GetValue(SelectAllTextOnFocusProperty);
    }

    public static void SetSelectAllTextOnFocus(TextBox textBox, bool value)
    {
        textBox.SetValue(SelectAllTextOnFocusProperty, value);
    }

    public static readonly DependencyProperty SelectAllTextOnFocusProperty =
        DependencyProperty.RegisterAttached(
            "SelectAllTextOnFocus",
            typeof (bool),
            typeof (TextBoxBehavior),
            new UIPropertyMetadata(false, OnSelectAllTextOnFocusChanged));

    private static void OnSelectAllTextOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textBox = d as TextBox;
        if (textBox == null) return;

        if (e.NewValue is bool == false) return;

        if ((bool) e.NewValue)
        {
            textBox.GotFocus += SelectAll;
            textBox.PreviewMouseDown += IgnoreMouseButton;
        }
        else
        {
            textBox.GotFocus -= SelectAll;
            textBox.PreviewMouseDown -= IgnoreMouseButton;
        }
    }

    private static void SelectAll(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox == null) return;
        textBox.SelectAll();
    }

    private static void IgnoreMouseButton(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox == null || (!textBox.IsReadOnly && textBox.IsKeyboardFocusWithin)) return;

        e.Handled = true;
        textBox.Focus();
    }
}

Anda kemudian dapat menggunakannya di XAML Anda seperti ini:

<TextBox Text="Some Text" behaviors:TextBoxBehavior.SelectAllTextOnFocus="True"/>

Saya menulis blog di sini .

Dutts
sumber
Saya suka pendekatan ini tetapi metode Get / Set tidak boleh diakhiri dengan "Properti"; Saya harus menghapusnya untuk mendapatkan kompilasi kode setelah menambahkan bagian Xaml.
Patrick Quirk
Sangat bagus, bekerja seperti yang diharapkan. Saya suka ini karena ini membantu saya menjaga perhatian View terpisah ketika melakukan MVVM.
Killnine
16

Berikut ini adalah solusi sangat sederhana yang sangat bagus di MSDN :

<TextBox
    MouseDoubleClick="SelectAddress"
    GotKeyboardFocus="SelectAddress"
    PreviewMouseLeftButtonDown="SelectivelyIgnoreMouseButton" />

Berikut kode di belakang:

private void SelectAddress(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        tb.SelectAll();
    }
}

private void SelectivelyIgnoreMouseButton(object sender,
    MouseButtonEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        if (!tb.IsKeyboardFocusWithin)
        {
            e.Handled = true;
            tb.Focus();
        }
    }
}
BillBR
sumber
1
Pada dasarnya, ini adalah solusi yang sama dengan yang berperingkat tertinggi di utas ini. Tapi sejak dua tahun sebelumnya, sekarang saya tahu darimana @Donnelle meminjamnya;)
Sergey Aldoukhov
Solusi ini sepertinya yang paling mudah dan berhasil untuk saya. Saya ingin subset teks tertentu dipilih secara default ketika memasuki kotak teks.
Jack B Nimble
10

Saya pikir ini bekerja dengan baik:

private void ValueText_GotFocus(object sender, RoutedEventArgs e)
{
    TextBox tb = (TextBox)e.OriginalSource;
    tb.Dispatcher.BeginInvoke(
        new Action(delegate
            {
                tb.SelectAll();
            }), System.Windows.Threading.DispatcherPriority.Input);
}

Jika Anda ingin menerapkannya sebagai metode ekstensi:

public static void SelectAllText(this System.Windows.Controls.TextBox tb)
{
    tb.Dispatcher.BeginInvoke(
        new Action(delegate
        {
            tb.SelectAll();
        }), System.Windows.Threading.DispatcherPriority.Input);
}

Dan di GotFocusacara Anda :

private void ValueText_GotFocus(object sender, RoutedEventArgs e)
{
    TextBox tb = (TextBox)e.OriginalSource;
    tb.SelectAllText();
}

Saya menemukan solusi di atas karena beberapa bulan yang lalu saya mencari cara untuk menetapkan fokus ke yang diberikan UIElement. Saya menemukan kode di bawah ini di suatu tempat (kredit diberikan dengan ini) dan berfungsi dengan baik. Saya mempostingnya meskipun itu tidak secara langsung terkait dengan pertanyaan OP karena itu menunjukkan pola penggunaan yang sama Dispatcheruntuk bekerja dengan a UIElement.

// Sets focus to uiElement
public static void DelayedFocus(this UIElement uiElement)
{
    uiElement.Dispatcher.BeginInvoke(
    new Action(delegate
    {
        uiElement.Focusable = true;
        uiElement.Focus();
        Keyboard.Focus(uiElement);
    }),
    DispatcherPriority.Render);
}
Sam
sumber
Saya kira ini adalah metode paling sederhana untuk diterapkan. setelah membuat metode ekstensi, Anda hanya perlu memanggil myTextBox.SelectAllText (). Mengapa jawaban ini tidak menerima poin lebih banyak? mengapa solusi lain jauh lebih baik?
Tono Nam
2
Saya akan menghindari metode ini karena ini bergantung pada panggilan async untuk dijalankan setelah penangan mouseUp kotak teks. Saya tidak akan percaya ini menjadi 100% deterministik, dan dapat menyebabkan perilaku yang tidak konsisten. Meskipun mungkin tidak mungkin terjadi, saya lebih suka pergi dengan metode jitu di atas.
Rob H
6

Berikut ini adalah upaya untuk memecahkan beberapa masalah dengan solusi lain:

  1. Menggunakan menu konteks klik kanan untuk cut / copy / past memilih semua teks bahkan jika Anda tidak memilih semuanya.
  2. Ketika kembali dari menu konteks klik kanan, semua teks selalu dipilih.
  3. Ketika kembali ke aplikasi dengan Alt+Tab , semua teks selalu dipilih.
  4. Ketika mencoba untuk memilih hanya sebagian dari teks pada klik pertama, semua selalu dipilih (tidak seperti bilah alamat Google misalnya).

Kode yang saya tulis dapat dikonfigurasi. Anda dapat memilih apa tindakan pilih semua perilaku harus terjadi dengan menetapkan tiga bidang dibaca: SelectOnKeybourdFocus, SelectOnMouseLeftClick,SelectOnMouseRightClick .

Kelemahan dari solusi ini adalah lebih rumit dan keadaan statis disimpan. Sepertinya perjuangan buruk dengan perilaku default dari TextBoxkontrol. Namun, ia berfungsi dan semua kode disembunyikan di kelas kontainer Properti Terlampir.

public static class TextBoxExtensions
{
    // Configuration fields to choose on what actions the select all behavior should occur.
    static readonly bool SelectOnKeybourdFocus = true;
    static readonly bool SelectOnMouseLeftClick = true;
    static readonly bool SelectOnMouseRightClick = true;

    // Remembers a right click context menu that is opened 
    static ContextMenu ContextMenu = null;

    // Remembers if the first action on the TextBox is mouse down 
    static bool FirstActionIsMouseDown = false;

    public static readonly DependencyProperty SelectOnFocusProperty =
        DependencyProperty.RegisterAttached("SelectOnFocus", typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false, new PropertyChangedCallback(OnSelectOnFocusChanged)));

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static bool GetSelectOnFocus(DependencyObject obj)
    {
        return (bool)obj.GetValue(SelectOnFocusProperty);
    }

    public static void SetSelectOnFocus(DependencyObject obj, bool value)
    {
        obj.SetValue(SelectOnFocusProperty, value);
    }

    private static void OnSelectOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (!(d is TextBox textBox)) return;

        if (GetSelectOnFocus(textBox))
        {
            // Register events
            textBox.PreviewMouseDown += TextBox_PreviewMouseDown;
            textBox.PreviewMouseUp += TextBox_PreviewMouseUp;
            textBox.GotKeyboardFocus += TextBox_GotKeyboardFocus;
            textBox.LostKeyboardFocus += TextBox_LostKeyboardFocus;
        }
        else
        {
            // Unregister events
            textBox.PreviewMouseDown -= TextBox_PreviewMouseDown;
            textBox.PreviewMouseUp -= TextBox_PreviewMouseUp;
            textBox.GotKeyboardFocus -= TextBox_GotKeyboardFocus;
            textBox.LostKeyboardFocus -= TextBox_LostKeyboardFocus;
        }
    }

    private static void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // If mouse clicked and focus was not in text box, remember this is the first click.
        // This will enable to prevent select all when the text box gets the keyboard focus 
        // right after the mouse down event.
        if (!textBox.IsKeyboardFocusWithin)
        {
            FirstActionIsMouseDown = true;
        }
    }

    private static void TextBox_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Select all only if:
        // 1) SelectOnMouseLeftClick/SelectOnMouseRightClick is true and left/right button was clicked
        // 3) This is the first click
        // 4) No text is selected
        if (((SelectOnMouseLeftClick && e.ChangedButton == MouseButton.Left) || 
            (SelectOnMouseRightClick && e.ChangedButton == MouseButton.Right)) &&
            FirstActionIsMouseDown &&
            string.IsNullOrEmpty(textBox.SelectedText))
        {
            textBox.SelectAll();
        }

        // It is not the first click 
        FirstActionIsMouseDown = false;
    }

    private static void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Select all only if:
        // 1) SelectOnKeybourdFocus is true
        // 2) Focus was not previously out of the application (e.OldFocus != null)
        // 3) The mouse was pressed down for the first after on the text box
        // 4) Focus was not previously in the context menu
        if (SelectOnKeybourdFocus &&
            e.OldFocus != null &&
            !FirstActionIsMouseDown &&
            !IsObjectInObjectTree(e.OldFocus as DependencyObject, ContextMenu))
        {
            textBox.SelectAll();
        }

        // Forget ContextMenu
        ContextMenu = null;
    }

    private static void TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Remember ContextMenu (if opened)
        ContextMenu = e.NewFocus as ContextMenu;

        // Forget selection when focus is lost if:
        // 1) Focus is still in the application
        // 2) The context menu was not opened
        if (e.NewFocus != null
            && ContextMenu == null)
        {
            textBox.SelectionLength = 0;
        }
    }

    // Helper function to look if a DependencyObject is contained in the visual tree of another object
    private static bool IsObjectInObjectTree(DependencyObject searchInObject, DependencyObject compireToObject)
    {
        while (searchInObject != null && searchInObject != compireToObject)
        {
            searchInObject = VisualTreeHelper.GetParent(searchInObject);
        }

        return searchInObject != null;
    }
}

Untuk memasang Properti Terlampir ke a TextBox , semua yang perlu Anda lakukan adalah menambahkan namespace xml ( xmlns) dari Properti Terlampir dan kemudian menggunakannya seperti ini:

<TextBox attachedprop:TextBoxExtensions.SelectOnFocus="True"/>

Beberapa catatan tentang solusi ini:

  1. Untuk mengganti perilaku default acara mouse-down dan mengaktifkan hanya memilih bagian dari teks pada klik pertama, semua teks dipilih pada acara mouse-up.
  2. Aku harus berurusan dengan fakta TextBoxmengingat seleksi setelah kehilangan fokus. Saya sebenarnya telah menimpa perilaku ini.
  3. Saya harus ingat jika tombol mouse di bawah adalah tindakan pertama di Internet TextBox (FirstActionIsMouseDown bidang statis).
  4. Saya harus mengingat menu konteks yang dibuka oleh klik kanan ( ContextMenubidang statis).

Satu-satunya efek samping yang saya temukan adalah kapan SelectOnMouseRightClickbenar. Kadang-kadang menu konteks klik kanan berkedip ketika itu dibuka dan mengklik kanan pada kosong di TextBoxtidak melakukan "pilih semua".

Eliahu Aaron
sumber
5

Saya menemukan tidak ada jawaban yang disajikan di sini meniru kotak teks Windows standar. Misalnya, coba klik di ruang putih antara karakter terakhir dari kotak teks dan sisi kanan kotak teks. Sebagian besar solusi di sini akan selalu memilih seluruh konten, yang membuatnya sangat sulit untuk menambahkan teks ke kotak teks.

Jawaban yang saya sajikan di sini berperilaku lebih baik dalam hal ini. Ini adalah perilaku (sehingga membutuhkan perakitan System.Windows.Interactivity dari Blend SDK ). Itu bisa ditulis ulang menggunakan properti terlampir juga.

public sealed class SelectAllTextOnFocusBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_PreviewMouseLeftButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObject_PreviewMouseLeftButtonDown;
    }

    void AssociatedObject_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // Find the textbox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        var textBox = parent as TextBox;
        Debug.Assert(textBox != null);

        if (textBox.IsFocused) return;

        textBox.SelectAll();
        Keyboard.Focus(textBox);
        e.Handled = true;
    }
}

Ini berdasarkan kode yang saya temukan di sini .

Kristof Verbiest
sumber
1
Meskipun ini adalah jawaban yang baik, saya pikir ketika pengguna mengklik ruang putih niatnya (dalam aplikasi bisnis) kemungkinan besar akan mengesampingkan seluruh nilai, jadi memilih semua adalah pendekatan yang tepat.
Sergey Aldoukhov
1
Sergey: klik pertama akan memilih seluruh nilai, klik kedua akan meletakkan kursor di sebelah kanan nilai. Dalam solusi lain yang disajikan, klik kedua akan menjaga seluruh nilai yang dipilih, sehingga sangat sulit untuk menambahkan nilai.
Kristof Verbiest
Bagaimana ini digunakan? Saya menambahkan kode ini ke App.xaml.cs tetapi tampaknya tidak berpengaruh pada TextBox di aplikasi saya.
PIntag
5

Implementasi sederhana ini berfungsi dengan baik untuk saya:

void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    ((TextBox) sender).SelectAll();
}

void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var TextBox = (TextBox) sender;
    if (!TextBox.IsKeyboardFocusWithin)
    {
        TextBox.Focus();
        e.Handled = true;
    }
}

Untuk menerapkannya ke semua TextBox, masukkan kode berikut setelahInitializeComponent();

EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus));
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseDownEvent, new MouseButtonEventHandler(TextBox_PreviewMouseDown));
Danny Beckett
sumber
4

Dalam file App.xaml:

<Application.Resources>
    <Style TargetType="TextBox">
        <EventSetter Event="GotKeyboardFocus" Handler="TextBox_GotKeyboardFocus"/>
    </Style>
</Application.Resources>

Dalam file App.xaml.cs:

private void TextBox_GotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
{
    ((TextBox)sender).SelectAll();
}

Dengan kode ini Anda menjangkau semua TextBoxdalam aplikasi Anda.

Darshan Faldu
sumber
3

Diambil dari sini :

Daftarkan event handler global dalam file App.xaml.cs:

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),TextBox.GotFocusEvent,
    new RoutedEventHandler(TextBox_GotFocus));

    base.OnStartup(e);
}

Kemudian pawang sederhana:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}
Neomoon
sumber
3

Saya menyadari ini sangat tua, tetapi di sini adalah solusi saya yang didasarkan pada ekspresi / microsoft interaktivitas dan ruang nama interaksi.

Pertama, saya mengikuti instruksi di tautan ini untuk menempatkan pemicu interaktivitas ke dalam gaya.

Lalu turun ke ini

<Style x:Key="baseTextBox" TargetType="TextBox">
  <Setter Property="gint:InteractivityItems.Template">
    <Setter.Value>
      <gint:InteractivityTemplate>
        <gint:InteractivityItems>
          <gint:InteractivityItems.Triggers>
            <i:EventTrigger EventName="GotKeyboardFocus">
              <ei:CallMethodAction MethodName="SelectAll"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
              <ei:CallMethodAction MethodName="TextBox_PreviewMouseLeftButtonDown"
                TargetObject="{Binding ElementName=HostElementName}"/>
            </i:EventTrigger>
          </gint:InteractivityItems.Triggers>
        </gint:InteractivityItems>
      </gint:InteractivityTemplate>
    </Setter.Value>
  </Setter>
</Style>

dan ini

public void TextBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
  TextBox tb = e.Source as TextBox;
  if((tb != null) && (tb.IsKeyboardFocusWithin == false))
  {
    tb.Focus();
    e.Handled = true;
  }
}

Dalam kasus saya, saya memiliki kontrol pengguna di mana kotak teks yang memiliki kode di belakang. Kode-belakang memiliki fungsi handler. Saya memberi nama kontrol pada pengguna saya di XAML, dan saya menggunakan nama itu untuk elemen. Ini bekerja dengan baik untuk saya. Cukup terapkan gaya ke TextBoxmana pun Anda ingin memiliki semua teks yang dipilih ketika Anda mengklik diTextBox .

Yang pertama CallMethodActionmemanggil metode kotak teks SelectAllketika GotKeyboardFocusacara TextBoxmenyala.

Saya harap ini membantu.

wiyosaya
sumber
Karena ini adalah pertanyaan yang sangat lama, mungkin akan membantu jawaban Anda mendapatkan perhatian jika Anda menyebutkan mengapa seseorang mungkin memilih pendekatan ini.
divibisan
Pertama, ini tidak perlu diletakkan dalam gaya, tapi saya pikir itu jelas bahwa ada banyak kontrol kotak teks yang membutuhkan ini, gaya adalah cara untuk pergi.
wiyosaya
1
Mungkin beberapa orang tidak akan setuju dengan pendekatan ini, namun, mengapa Anda mungkin menggunakan pendekatan ini, itu tidak memerlukan subkelas TextBox, mendaftarkan event handler kelas, metode ekstensi, membuat properti terlampir, dll. Sebagai suatu gaya, bisa juga ditambahkan ke kamus sumber daya dari setiap proyek xaml. Tanpa Kunci x:, itu akan diterapkan pada instance TextBox dalam lingkup kamus sumber daya tanpa harus mengubah xaml dari masing-masing kotak teks. Dalam beberapa kasus, ini mungkin merupakan pendekatan yang lebih bersih.
wiyosaya
2

Saya telah menggunakan jawaban Nils tetapi dikonversi menjadi lebih fleksibel.

public enum SelectAllMode
{

    /// <summary>
    ///  On first focus, it selects all then leave off textbox and doesn't check again
    /// </summary>
    OnFirstFocusThenLeaveOff = 0,

    /// <summary>
    ///  On first focus, it selects all then never selects
    /// </summary>
    OnFirstFocusThenNever = 1,

    /// <summary>
    /// Selects all on every focus
    /// </summary>
    OnEveryFocus = 2,

    /// <summary>
    /// Never selects text (WPF's default attitude)
    /// </summary>
    Never = 4,
}

public partial class TextBox : DependencyObject
{
    public static readonly DependencyProperty SelectAllModeProperty = DependencyProperty.RegisterAttached(
        "SelectAllMode",
        typeof(SelectAllMode?),
        typeof(TextBox),
        new PropertyMetadata(SelectAllModePropertyChanged));

    private static void SelectAllModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is System.Windows.Controls.TextBox)
        {
            var textBox = d as System.Windows.Controls.TextBox;

            if (e.NewValue != null)
            {
                textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
            }
            else
            {
                textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
            }
        }
    }

    private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DependencyObject dependencyObject = GetParentFromVisualTree(e.OriginalSource);

        if (dependencyObject == null)
            return;

        var textBox = (System.Windows.Controls.TextBox)dependencyObject;
        if (!textBox.IsKeyboardFocusWithin)
        {
            textBox.Focus();
            e.Handled = true;
        }
    }

    private static DependencyObject GetParentFromVisualTree(object source)
    {
        DependencyObject parent = source as UIElement;
        while (parent != null && !(parent is System.Windows.Controls.TextBox))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }

        return parent;
    }

    private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
    {
        var textBox = e.OriginalSource as System.Windows.Controls.TextBox;
        if (textBox == null) return;

        var selectAllMode = GetSelectAllMode(textBox);

        if (selectAllMode == SelectAllMode.Never)
        {
            textBox.SelectionStart = 0;
            textBox.SelectionLength = 0;
        }
        else
            textBox.SelectAll();

        if (selectAllMode == SelectAllMode.OnFirstFocusThenNever)
            SetSelectAllMode(textBox, SelectAllMode.Never);
        else if (selectAllMode == SelectAllMode.OnFirstFocusThenLeaveOff)
            SetSelectAllMode(textBox, null);
    }

    [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(System.Windows.Controls.TextBox))]
    public static SelectAllMode? GetSelectAllMode(DependencyObject @object)
    {
        return (SelectAllMode)@object.GetValue(SelectAllModeProperty);
    }

    public static void SetSelectAllMode(DependencyObject @object, SelectAllMode? value)
    {
        @object.SetValue(SelectAllModeProperty, value);
    }
}

Di XAML, Anda dapat menggunakan seperti ini:

<!-- On first focus, it selects all then leave off textbox and doesn't check again -->
<TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenLeaveOff" />

<!-- On first focus, it selects all then never selects -->
<TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenNever" />

<!-- Selects all on every focus -->
<TextBox attprop:TextBox.SelectAllMode="OnEveryFocus" />

<!-- Never selects text (WPF's default attitude) -->
<TextBox attprop:TextBox.SelectAllMode="Never" />
bafsar
sumber
1
Solusi yang sangat bagus untuk digunakan dalam template karena Anda dapat mengikatnya ke xaml tanpa codebehind yang sebenarnya, hanya memperpanjang perilaku kotak teks.
Eric Johansson
2

Ini adalah versi C # dari jawaban yang diposting oleh @Nasenbaer

private delegate void TextBoxSelectAllDelegate(object sender);

private void TextBoxSelectAll(object sender)
{
    (sender as System.Windows.Controls.TextBox).SelectAll();
}

private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
    TextBoxSelectAllDelegate d = TextBoxSelectAll;

    this.Dispatcher.BeginInvoke(d,
        System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
}

sedangkan MyTextBox_GotFocusevent handler ditugaskan untuk GotFocusacara MyTextBox.

ViRuSTriNiTy
sumber
2

Saya punya jawaban yang sedikit disederhanakan untuk ini (hanya PreviewMouseLeftButtonDownacara) yang sepertinya meniru fungsi browser yang biasa:

Di XAML Anda memiliki TextBoxsuara:

<TextBox Text="http://www.blabla.com" BorderThickness="2" BorderBrush="Green" VerticalAlignment="Center" Height="25"
                 PreviewMouseLeftButtonDown="SelectAll" />

Dalam codebehind:

private void SelectAll(object sender, MouseButtonEventArgs e)
{
    TextBox tb = (sender as TextBox);

    if (tb == null)
    {
        return;
    }

    if (!tb.IsKeyboardFocusWithin)
    {
        tb.SelectAll();
        e.Handled = true;
        tb.Focus();
    }
}
Danield
sumber
1
Mungkin ingin menambahkan acara GotKeyboardFocus dengan TextBox.SelectAll () di dalam untuk orang-orang yang menabrak aplikasi Anda. Solusi Anda juga berfungsi untuk Kotak Kata Sandi (karena Kotak Kata Sandi adalah tipe yang disegel, mereka tidak dapat diperpanjang).
David Sherret
1

Coba metode ekstensi ini untuk menambahkan perilaku yang diinginkan ke kontrol TextBox apa pun. Saya belum mengujinya secara ekstensif, tetapi tampaknya memenuhi kebutuhan saya.

public static class TextBoxExtensions
{
    public static void SetupSelectAllOnGotFocus(this TextBox source)
    {
        source.GotFocus += SelectAll;
        source.PreviewMouseLeftButtonDown += SelectivelyIgnoreMouseButton;
    }

    private static void SelectAll(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }

    private static void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {
            if (!textBox.IsKeyboardFocusWithin)
            {
                e.Handled = true;
                textBox.Focus();
            }
        }
    }
}
David Kirkland
sumber
1

Saya mencari banyak solusinya, saya menemukan beberapa solusi untuk memilih semua. Namun, masalahnya adalah ketika kita melakukan klik kanan dan memotong / menyalin setelah memilih bagian teks dari kotak teks, ia memilih semua bahkan saya memilih bagian teks. Untuk memperbaikinya di sini adalah solusinya. Cukup tambahkan kode di bawah ini di acara pilih keyboard. Ini berhasil untuk saya.

private static void SelectContentsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (d is TextBox)
    {
        TextBox textBox = d as TextBox;
        if ((e.NewValue as bool?).GetValueOrDefault(false))
        {
            textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;                 
        }
        else
        {
            textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;

        }
    }
}


private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
{
    if (e.KeyboardDevice.IsKeyDown(Key.Tab))
        ((TextBox)sender).SelectAll();
}
Sambu Praveen
sumber
1

Saya memiliki masalah yang sama. Di VB.Net cara kerjanya mudah:

VB XAML:

<TextBox x:Name="txtFilterFrequency" />

Kode belakang:

Private Sub txtFilterText_GotFocus(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles txtFilterText.GotFocus
    Me.Dispatcher.BeginInvoke(Sub()
                                  txtFilterText.SelectAll()
                              End Sub, DispatcherPriority.ApplicationIdle, Nothing)
End Sub

C # (terima kasih kepada ViRuSTriNiTy)

private delegate void TextBoxSelectAllDelegate(object sender);

private void TextBoxSelectAll(object sender)
{
    (sender as System.Windows.Controls.TextBox).SelectAll();
}

private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
    TextBoxSelectAllDelegate d = TextBoxSelectAll;

    this.Dispatcher.BeginInvoke(d,
        System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
}
Nasenbaer
sumber
Solusi terbaik untuk saya, saya telah memposting terjemahan C # di sini: stackoverflow.com/a/48385409/3936440
ViRuSTriNiTy
Bagi saya, pendekatan ini terkadang gagal untuk memilih teks. Saya pikir ini kondisi balapan karena BeginInvoke.
Vimes
Silakan tentukan. Prioritas operator bekerja pada aplikasi default seperti yang diharapkan. Apa situasimu Apakah Anda mencoba tepat seperti yang dijelaskan? Adakah yang spesial dalam solusi Anda?
Nasenbaer
1

Sejauh ini, ini adalah solusi paling sederhana.

Tambahkan global handler ke aplikasi (App.xaml.cs) dan selesai. Anda hanya perlu beberapa baris kode.

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),
        TextBox.GotFocusEvent,
        new RoutedEventHandler(TextBox_GotFocus));

    base.OnStartup(e);
}

Jadi gunakan kelas EventManager untuk mendaftarkan pengendali event global terhadap suatu tipe (TextBox). Pawang yang sebenarnya mati sederhana:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}

Periksa di sini: WPF TextBox SelectAll on Focus

Semoga ini bisa membantu.

Marlon Assef
sumber
1

Bagi mereka yang tertarik dengan pendekatan Donnelle / Groky, tetapi ingin klik di sebelah kanan karakter terakhir (tetapi masih di dalam TextBox) untuk menempatkan tanda sisipan di akhir teks yang dimasukkan, saya telah datang dengan solusi ini:

int GetRoundedCharacterIndexFromPoint(TextBox textBox, Point clickedPoint)
{
    int position = textBox.GetCharacterIndexFromPoint(clickedPoint, true);

    // Check if the clicked point is actually closer to the next character
    // or if it exceeds the righmost character in the textbox
    // (in this case return increase the position by 1)
    Rect charLeftEdge = textBox.GetRectFromCharacterIndex(position, false);
    Rect charRightEdge = textBox.GetRectFromCharacterIndex(position, true);
    double charWidth = charRightEdge.X - charLeftEdge.X;
    if (clickedPoint.X + charWidth / 2 > charLeftEdge.X + charWidth) position++;

    return position;
}

void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
{
    // Find the TextBox
    DependencyObject parent = e.OriginalSource as UIElement;
    while (parent != null && !(parent is TextBox))
        parent = VisualTreeHelper.GetParent(parent);

    if (parent != null)
    {
        var textBox = (TextBox)parent;
        if (!textBox.IsKeyboardFocusWithin)
        {
            // If the text box is not yet focused, give it the focus and
            // stop further processing of this click event.
            textBox.Focus();
            e.Handled = true;
        }
        else
        {
            int pos = GetRoundedCharacterIndexFromPoint(textBox, e.GetPosition(textBox));
            textBox.CaretIndex = pos;
        }
    }
}

void SelectAllText(object sender, RoutedEventArgs e)
{
    var textBox = e.OriginalSource as TextBox;
    if (textBox != null)
        textBox.SelectAll();
}

The GetRoundedCharacterIndexFromPointMetode diambil dari ini posting.

PIntag
sumber
1
Berfungsi dengan baik, tetapi acara klik ganda tidak dipicu
Rodrigo Caballero
Sebenarnya itu masuk ke acara double-klik tapi properti OriginalSource adalah tipe TextBoxView. Jadi metode SelectAllText harus seperti ini: private static void SelectAllText (pengirim objek, RoutedEventArgs e) {var textBox = e.OriginalSource as TextBox; if (textBox! = null) {textBox.SelectAll (); System.Diagnostics.Debug.WriteLine ("Selected ALL"); } lain jika (pengirim adalah TextBox) {(pengirim sebagai TextBox) .SelectAll (); }
Rodrigo Caballero
1

Setelah googling dan pengujian, saya menemukan solusi sederhana yang bekerja untuk saya.

Anda perlu menambahkan pengendali acara ke Loadedacara jendela kontainer Anda:

private void yourwindow_Loaded(object sender, RoutedEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),
        TextBox.PreviewMouseLeftButtonDownEvent,
        new RoutedEventHandler(SelectivelyIgnoreMouseButton));
}

Selanjutnya, Anda harus membuat handler ke kode referensi RoutedEventHandlersebelumnya:

private void SelectivelyIgnoreMouseButton(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        if (!tb.IsKeyboardFocusWithin)
        {
            e.Handled = true;
            tb.Focus();
        }
    }
}

Sekarang, Anda dapat menambahkan SelectAll()perintah pada GotFocuspengendali acara ke TextBoxkontrol apa pun secara terpisah:

private void myTextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}

Teks Anda sekarang dipilih pada fokus!

Diadaptasi dari solusi Dr. WPF, Forum MSDN

DonBeto97
sumber
Saya baru saja menggunakan: private async void TBTime_GotFocus (pengirim objek, RoutedEventArgs e) {TextBox tb = (TextBox) e.OriginalSource; tunggu Dispatcher.RunAsync (Windows.UI.Core.CoreDispatcherPriority.Normal, async () => {tb.SelectAll ();}); }
David Jones
1
#region TextBoxIDCard selection
private bool textBoxIDCardGotFocus = false;
private void TextBoxIDCard_GotFocus(object sender, RoutedEventArgs e)
{
    this.TextBoxIDCard.SelectAll();
}

private void TextBoxIDCard_LostFocus(object sender, RoutedEventArgs e)
{
    textBoxIDCardGotFocus = false;
}

private void TextBoxIDCard_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if (textBoxIDCardGotFocus == false)
    {
        e.Handled = true;
        this.TextBoxIDCard.Focus();
        textBoxIDCardGotFocus = true;
    }
} 
#endregion
Brian
sumber
Jika Anda memiliki 20 kotak teks di jendela, apakah Anda akan membuat 3 metode untuk setiap kotak teks? Pendekatan ini tidak baik. Coba lihat di sini: rachel53461.wordpress.com/2011/11/05/…
Alexandru Dicu
0

Ini sepertinya bekerja dengan baik untuk saya. Ini pada dasarnya adalah rekap dari beberapa posting sebelumnya. Saya hanya memasukkan ini ke file MainWindow.xaml.cs saya di konstruktor. Saya membuat dua penangan, satu untuk keyboard, dan satu untuk mouse, dan menyalurkan kedua acara ke fungsi yang sama HandleGotFocusEvent,, yang didefinisikan tepat setelah konstruktor dalam file yang sama.

public MainWindow()
{
   InitializeComponent();

   EventManager.RegisterClassHandler(typeof(TextBox), 
      UIElement.GotKeyboardFocusEvent,
      new RoutedEventHandler(HandleGotFocusEvent), true);
   EventManager.RegisterClassHandler(typeof(TextBox),
      UIElement.GotMouseCaptureEvent,
      new RoutedEventHandler(HandleGotFocusEvent), true);   
}
private void HandleGotFocusEvent(object sender, RoutedEventArgs e)
{
   if (sender is TextBox)
      (sender as TextBox).SelectAll();
}
Ted
sumber
Bagus dan mudah, tetapi tampaknya memiliki masalah waktu - setiap percobaan lainnya (klik mouse), itu akan segera memilih lagi ...?
T4NK3R
0

Cara mudah untuk mengganti mouseDown dan memilih semua setelah klik dua kali adalah:

public class DoubleClickTextBox: TextBox
{

    public override void EndInit()
    {
        base.EndInit();            
    }

    protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
    {
        base.OnMouseEnter(e);
        this.Cursor = Cursors.Arrow;
    }
    protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
    {

    }

    protected override void OnMouseDoubleClick(System.Windows.Input.MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        this.SelectAll();
    }
}
Hesse
sumber
0

Coba letakkan ini di konstruktor kontrol apa pun yang menampung kotak teks Anda:

Loaded += (sender, e) =>
{
    MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    myTextBox.SelectAll();
}
CodeOtaku
sumber
Pendekatan ini tidak berfungsi ketika Anda meletakkan ini di konstruktor jendela.
ViRuSTriNiTy
0

Jika ada acara yang tidak memilih teks selama OnFocusmouse di atas, saya biasanya hanya menunda pilih semua.

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (TextBox.Text != null)
    {
        _ = Task.Run(() =>
        {
            Dispatcher.Invoke(
                async () => {
                    await Task.Delay(100);
                    TextBox.SelectAll();
                }
            );
        });
    }
}
milope
sumber
-1

Saya sudah menguji semuanya tetapi hanya yang berikut ini yang berhasil:

protected override void OnStartup(StartupEventArgs e) 
{
    EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewMouseLeftButtonDownEvent,
   new MouseButtonEventHandler(SelectivelyHandleMouseButton), true);
    EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotKeyboardFocusEvent,
      new RoutedEventHandler(SelectAllText), true);
    EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent,
      new RoutedEventHandler(GotFocus), true);          
}

private static void SelectivelyHandleMouseButton(object sender, MouseButtonEventArgs e)
{
    var textbox = (sender as TextBox);
    if (textbox != null)
    {
        int hc = textbox.GetHashCode();
        if (hc == LastHashCode)
        {
            if (e.OriginalSource.GetType().Name == "TextBoxView")
            {
                e.Handled = true;
                textbox.Focus();
                LastHashCode = -1;
            }
        }
    }
    if (textbox != null) textbox.Focus();
}

private static void SelectAllText(object sender, RoutedEventArgs e)
{
    var textBox = e.OriginalSource as TextBox;
    if (textBox != null)
        textBox.SelectAll();
}

private static int LastHashCode;
private static void GotFocus(object sender, RoutedEventArgs e)
{
    var textBox = e.OriginalSource as TextBox;
    if (textBox != null)
        LastHashCode = textBox.GetHashCode();
}
Ehsan Zargar Ershadi
sumber
4
Itu juga merupakan penyalahgunaan kode hash. Saya akan membaca ini, tautan
RichK
3
Dan menggunakan GetType().Namealih-alih isatau ascukup
rapi
-1

Saya melihat bahwa ada banyak jawaban, tetapi sebagai yang disetujui, metode yang harus digunakan adalah EditTextBoxGotCapture

dengan kode berikut di belakang:

private void EditTextBoxGotCapture(object sender, MouseEventArgs e)
{
    if (sender is TextBox tb)
    {
        tb.Select(0, tb.Text.Length);
    }
}
Liviu Sosu
sumber