WPF TextBoxでフォーカスのあるすべてのテキストを自動的に選択する方法は?


232

イベントハンドラーSelectAllから呼び出した場合GotFocus、マウスでは機能しません-マウスを離すとすぐに選択が消えます。

編集:人々はドネルの答えが好きです、私はなぜそれが受け入れられた答えほど好きではなかったのかを説明しようとします。

  • それはより複雑ですが、受け入れられた答えは同じことをより簡単な方法で行います。
  • 受け入れられた回答の使いやすさは優れています。テキストの中央をクリックすると、マウスを離すとテキストの選択が解除され、すぐに編集を開始できます。それでもすべてを選択したい場合は、もう一度ボタンを押すだけで、リリース時に選択が解除されません。ドネルのレシピに従って、テキストの真ん中をクリックした場合、編集するにはもう一度クリックする必要があります。テキスト内外のどこかをクリックした場合、おそらくすべてを上書きするのではなく、編集を開始したいということです。

複数のフォームを使用する場合、彼女の答えは最初のフォームよりも複雑さが少なくなります。どちらの機能も変更できるため、両方のオプションの使いやすさは重要ではありません。
thepaulpage

1
@Sergey:より良い回答があったため、この質問の承認済み回答を変更することをお勧めします。私は私を提案するつもりはありませんが、あなたはそうすることができます;)
Grokys

質問にはSilverlightタグがありますが、Silverlightにはほとんどのイベント/あらゆる種類のプレビューイベントがありません。Silverlightにはどのソリューションを使用する必要がありますか?
Valentin Kuzub、2011年

リンク "WPFでフォーカスが難しいのはなぜですか?" が壊れている
マクセンス2014年

1
以下のstackoverflow.com/a/2553297/492のコメントで述べたように、madprops.org / blog / wpf - textbox - selectall - on - focusは簡単な解決策であり、元のnouseの動作を維持します。アプリにはWPFコントロールが1つしかないため、イベント登録をコンストラクターに配置しました。
CADは、2015

回答:


75

GotFocusイベントで選択が失われる理由がわかりません。

しかし、1つの解決策は、GotKeyboardFocusおよびGotMouseCaptureイベントの選択を行うことです。そうすれば、常に機能します。


10
いいえ。既存のテキストの真ん中をマウスでクリックすると、マウスボタンを離すとすぐに選択が失われます。
セルゲイアルドゥホフ2009年

3
ただし、2回目のシングルクリックの後、すべてのテキストが再度選択されます... WPFデザイナーの意図した動作かどうかはわかりませんが、使いやすさはそれほど悪くありません。単一のGotFocusハンドラーとのもう1つの違いは、TextBoxの空のスペースをクリックするとすべてが選択されることです。
セルゲイアルドゥホフ2009年

3
これも私の最初の解決策でした。しかし、私は、ユーザーが実際に彼らがしている毎回、彼らは全体のテキストをクリックしているため、マウスを使用してテキストを選択することができないが選択されますと、イライラしていることがわかった...
ニルス

1
このソリューションのもう1つの欠点は、TextBoxの[切り取り/コピー/貼り付け]メニューを使用すると、メニュー項目を選択するとテキスト全体が選択されることです。

@gcoresこれが古いことは知っていますが、GotFocusイベントで選択したテキストが失われる理由を誰かが知っていますか?それは他のイベントで機能することについてあなたは正しいです、そしてそれは私の本の中で完全に受け入れられる解決策です。
装う

210

最初のクリックですべてが選択され、次のクリックでカーソルが移動するようになっています(このアプリケーションはペン付きタブレットで使用するように設計されています)。

あなたはそれが役に立つかもしれません。

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();
    }
}

9
どうもありがとうございました。これは素晴らしく働き、私見の受け入れられた答えであるはずです。上記のコードは、TextBoxがキーボードまたはマウス(そして明らかにスタイラス)を介してフォーカスを受け取ったときに機能します。+1
ドリューノークス

5
ここでほぼ同じ答えがsocial.msdn.microsoft.com/Forums/en-US/wpf/thread/…にありましたが、e.OriginalSourceを使用せず、ビジュアルツリーをクロールしなくても機能します。これをすべて行うことに利点はありますか?
Marco Luglio、

1
うまく機能しますが、それでもマウスでテキストをドラッグ選択できる場合は完璧です。Google Chromeのアドレスバーは理想的なシステムの完璧な例です。ユーザーがドラッグせずにクリックして離すと、テキスト全体が強調表示されます。ただし、ユーザーがクリックしてドラッグした場合、通常はすべてが選択されるのではなく、ドラッグによってテキストが選択されます。SelectAllはマウスリリースでのみ発生します。このデザインを改善できるかどうか、試してみます。
devios1

2
このソリューションのもう1つの欠点は、TextBoxの[切り取り/コピー/貼り付け]メニューを使用すると、メニュー項目を選択するとテキスト全体が選択されることです。

1
私はSelectAllText方法の追加テストtextBox.IsFocusedがそれを改善することを発見しました。GetKeyboardFocusプログラムへのalt-tabキーによるものである場合は、すべてを選択する必要はありません。
スコットスタッフォード

164

Donnelleの答えは最も効果的ですが、それを使用するために新しいクラスを派生させる必要があるのは苦痛です。

それを行う代わりに、アプリケーション内のすべてのTextBoxのハンドラーをApp.xaml.csにハンドラーを登録します。これにより、標準のTextBoxコントロールでDonnelleの回答を使用できます。

次のメソッドをApp.xaml.csに追加します。

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();
    }
}

4
これはかなりクールなソリューションであり、Matt Hamiltonが
Ashley Davis


2
ありがとう、ネイト、修正済みですが、私の弁護では、スペルミスは
ドンネル

質問にはSilverlightタグがありますが、Silverlightにはほとんどのイベント/あらゆる種類のプレビューイベントがありません。Silverlightにはどのソリューションを使用する必要がありますか?事前の感謝
バレンティンクズブ

4
「スペリングに焦点を当てたものは米国でははるかに一般的ですが、イギリスとカナダでは時々使用され、オーストラリアとニュージーランドでは特に一般的です。」So nyah;)
Donnelle

85

これはかなり古いですが、とにかく答えを表示します。

私はこれをより自然だと思うので、(ダブルクリックをスキップして)Donnelleの回答の一部を選択しました。ただし、gcoresのように、派生クラスを作成する必要がありません。しかし、私はgcores OnStartupメソッドも好きではありません。そして、私はこれを「一般的ではあるが常にではない」基準で必要としています。

これをアタッチメントとして実装したDependencyPropertyのでlocal:SelectTextOnFocus.Active = "True"、xamlで設定できます。私はこの方法が最も楽しいと思います。

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);
    }
}

私の「常にではないが一般的な」機能では、このAttacheプロパティをTrue(グローバル)に設定しTextBox Styleます。このように「テキストの選択」は常に「オン」ですが、テキストボックスごとに無効にすることができます。


8
+1これはグローバルに設定するよりもはるかに優れており、TextBoxから派生するよりも「WPFの方法」です。
stijn

3
+1 stijnに同意します。app.csでコードを「非表示」にすることは、なぜSelectAllOnFocusが発生しているのかを理解しなければならない貧しい開発者には不向きです。:-)これをTextBoxBehaviorsのクラスにドロップし、ベースのTextBoxスタイルを更新しました。御馳走を働いた。乾杯
リーキャンベル

2
@tronda:TextBoxのTargetTypeを使用して、リソースにスタイルを追加するだけです。wpftutorial.net/Styles.htmlをご覧
Nils

2
ベストアンサーのもう1つの+1。私が見つけた唯一の問題は、右マウスボタンを使用してもテキストが常に選択されることです。これは、コンテキストメニューを使用してテキストを編集するために頻繁に行います。この場合、ソリューションが機能しません。コンテキストメニューから1単語を切り取りたいだけでした。これを修正する方法を知っていますか?
user3313608

2
私はこの答えが好きですが、なぜDependencyObjectを拡張する必要があるのですか?私はそれを削除しました、そしてそれはまだうまく働きます。
フレッド

47

以下に、便利な回答ソリューションを実装するブレンド動作を示します。

1つは単一のTextBoxに接続するためのものです。

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;
        }
    }
}

そして、複数のTextBoxを含むコンテナのルートにアタッチするためのもの:

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();
    }
}

これは断然最良で最もクリーンなソリューションです。共有してくれてありがとう。
Golvellius 2013

見た目はいいのですが、何らかの理由でタブコントロールが機能しなくなります。
2013

ソリューションを使用したいのですが。しかし、本当に失われました...多分あなたはサンプルを持っていますか?
ファンパブロゴメス14

フォーカスがあるときにテキストボックス内のどこかをクリックすると(キャレットを別の場所に移動したい場合を想像してください)、キャレットを移動するのではなく、もう一度SelectAllを実行します。意外です。GotMouseCaptureを一般的なMouseDoubleClickに置き換えることで修正しました。MSDNの後者のソリューションに感謝します。
norekhov 2014

1
テキストボックスがFocusManager.FocusedElementを介して初期フォーカスを受け取ったときに機能しないようです。何かアイデアはありますか?
szx 2015

24

これは古い質問ですが、この問題が発生したばかりですが、Sergeyの回答のような式の動作ではなく、添付された動作を使用して解決しました。つまりSystem.Windows.Interactivity、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();
    }
}

その後、次のようにXAMLで使用できます。

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

私はそれについてここにブログを書い


私はこのアプローチが好きですが、Get / Setメソッドは「プロパティ」で終わるべきではありません。Xaml部分を追加した後にコードをコンパイルするには、それを削除する必要がありました。
Patrick Quirk 2013

とても素敵で、期待どおりに機能しました。MVVMを実行するときにViewの問題を分離しておくのに役立つので、これが好きです。
Killnine 2014年

16

MSDNの非常に優れた非常にシンプルなソリューションを次に示します

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

背後にあるコードは次のとおりです。

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();
        }
    }
}

1
基本的に、これはこのスレッドで最も評価の高いソリューションと同じです。しかし、2年前のことなので、@ Donnelleがどこからそれを借りたのかがわかります;)
セルゲイアルドゥホフ2013年

この解決策が最も簡単に思え、私にとってはうまくいきました。テキストボックスに入るときにデフォルトで選択されるテキストの特定のサブセットが欲しかった。
ジャックBニンブル2016

10

私はこれがうまくいくと思います:

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);
}

拡張メソッドとして実装したい場合:

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

そしてあなたのGotFocusイベントでは:

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

数か月前に特定のことに焦点を合わせる方法を探していたため、上記の解決策を見つけましたUIElement。以下のコードをどこかで発見しました(クレジットはここに記載されています)。OPの質問とは直接関係はありませんが、を使用Dispatcherするのと同じパターンを使用しているため、投稿し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);
}

これが実装する最も簡単な方法だと思います。拡張メソッドを作成した後は、myTextBox.SelectAllText()を呼び出すだけです。なぜこの回答はより多くのポイントを受け取っていないのですか?なぜ他のソリューションがこれほど優れているのですか?
遠野ナム

2
このメソッドは、テキストボックスのMouseUpハンドラーの後に実行される非同期呼び出しに依存しているため、避けます。これが100%確定的であるとは私は信頼せず、一貫性のない動作につながる可能性があります。それは起こりそうにないかもしれませんが、私はむしろ上記の確実な方法で行きたいです。
Rob H

6

他の解決策の問題のいくつかを解決する試みはここにあります:

  1. 切り取り/コピー/貼り付けの右クリックコンテキストメニューを使用すると、すべてを選択しなかった場合でも、すべてのテキストが選択されます。
  2. 右クリックのコンテキストメニューから戻ると、すべてのテキストが常に選択されます。
  3. Alt+ Tabでアプリケーションに戻ると、すべてのテキストが常に選択されます。
  4. 最初のクリックでテキストの一部のみを選択しようとすると、すべてが選択されます(たとえば、Google Chromeのアドレスバーとは異なります)。

私が書いたコードは構成可能です。:次の3つの読み取り専用フィールドを設定することで起こるべきである何の行動のすべての行動を選択する上で選択することができSelectOnKeybourdFocusSelectOnMouseLeftClickSelectOnMouseRightClick

このソリューションの欠点は、より複雑で静的な状態が保存されることです。これは、TextBoxコントロールのデフォルトの動作との醜い闘いのようです。それでも機能し、すべてのコードはAttached Propertyコンテナクラスに隠されています。

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;
    }
}

添付プロパティをにアタッチするにはTextBox、添付プロパティのxml名前空間(xmlns)を追加して、次のように使用するだけです。

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

このソリューションに関するいくつかのメモ:

  1. マウスダウンイベントのデフォルトの動作をオーバーライドし、最初のクリックでテキストの一部のみを選択できるようにするには、マウスアップイベントですべてのテキストを選択します。
  2. 私はTextBoxフォーカスが失われた後、その選択を記憶するという事実に対処しなければなりませんでした。私は実際にこの動作をオーバーライドしました。
  3. マウスボタンを押すことがTextBoxFirstActionIsMouseDown静的フィールド)の最初のアクションかどうかを覚えておく必要がありました。
  4. 右クリックで開いたコンテキストメニュー(ContextMenu静的フィールド)を覚えておく必要がありました。

私が見つけた唯一の副作用はいつSelectOnMouseRightClicktrueかです。右クリックコンテキストメニューを開いたときにブランクが右クリックしても、TextBox「すべて選択」されない場合があります。


5

ここに提示された回答のいずれも、標準のWindowsテキストボックスを模倣したものは見つかりませんでした。たとえば、テキストボックスの最後の文字とテキストボックスの右側の間の空白をクリックしてみてください。ここでのほとんどのソリューションは常にコンテンツ全体を選択するため、テキストをテキストボックスに追加することは非常に困難です。

ここで私が提示する答えは、この点でうまく機能します。これは動作です(そのため、Blend SDKのSystem.Windows.Interactivityアセンブリが必要です)。添付プロパティを使用して書き換えることもできます。

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;
    }
}

これは私がここで見つけたコードに基づいています。


1
これは良い答えですが、ユーザーがホワイトスペースをクリックしたときの意図は(ビジネスアプリケーションで)ほとんどの場合値全体を上書きすることなので、すべてを選択するのが正しい方法だと思います。
セルゲイアルドゥホフ2010

1
Sergey:最初のクリックで値全体が選択され、2回目のクリックで値の右側にカーソルが置かれます。他の提示されたソリューションでは、2回目のクリックで値全体が選択されたままになり、値に追加することが非常に困難になります。
クリストフヴェルビエスト2010

これはどのように使用されますか?このコードをApp.xaml.csに追加しましたが、アプリのTextBoxに影響がないようです。
PIntag 2011

5

この単純な実装は私にとって完璧に機能します:

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;
    }
}

すべてTextBoxのに適用するには、次のコードを後に置きますInitializeComponent();

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

4

App.xamlファイル:

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

App.xaml.csファイル:

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

このコードを使用するTextBoxと、アプリケーションのすべてに到達できます。


3

ここから撮影:

App.xaml.csファイルにグローバルイベントハンドラーを登録します。

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

    base.OnStartup(e);
}

その場合、ハンドラーは次のように単純です。

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

3

これは非常に古いことに気づきましたが、式/マイクロソフトの対話機能と対話の名前空間に基づいた私の解決策を次に示します。

まず、このリンクの指示に従ってインタラクティブトリガーをスタイルに配置しました。

それからこれに来ます

<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>

この

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;
  }
}

私の場合、テキストボックスが分離コードを持つユーザーコントロールがあります。分離コードにはハンドラー関数があります。ユーザーコントロールにXAMLで名前を付け、その名前を要素に使用しています。これは私にとって完璧に機能しています。TextBoxをクリックしたときにすべてのテキストを選択したい場所にスタイルを適用するだけですTextBox

最初のイベントは、イベントが発生したときにCallMethodActionテキストボックスのSelectAllメソッドを呼び出します。GotKeyboardFocusTextBox

これがお役に立てば幸いです。


これは非常に古い質問なので、なぜこのアプローチを選択するのかを説明すると、回答が注目されるのに役立ちます。
divibisan

まず、これをスタイルに入れる必要はありませんが、これを必要とする多くのテキストボックスコントロールがあることは明らかです。スタイルはその方法です。
wiyosaya

1
おそらくこのアプローチに同意しない人もいるかもしれませんが、このアプローチを使用する理由については、TextBoxのサブクラス化、クラスハンドラーイベントの登録、拡張メソッド、添付プロパティの作成などは必要ありません。スタイルとして追加することもできます。任意のxamlプロジェクトのリソースディクショナリに。x:Keyがない場合、個々のテキストボックスのxamlを変更する必要なく、リソースディクショナリのスコープ内の任意のTextBoxインスタンスに適用されます。場合によっては、よりクリーンなアプローチになることがあります。
wiyosaya

2

私はNilsの回答を使用しましたが、より柔軟に変換されました。

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);
    }
}

XAMLでは、次のいずれかのように使用できます。

<!-- 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" />

1
テキストボックスの拡張された動作だけで、実際のコードビハインドなしでそれをxamlにバインドできるため、テンプレートで使用するための本当に良いソリューション。
エリック・ヨハンソン

2

@Nasenbaerが投稿した回答の C#バージョンは次のとおりです

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);
}

一方 MyTextBox_GotFocus、のイベントに割り当てられたイベントハンドラGotFocusですMyTextBox


2

私はこれについて少し簡単な答えがあります( PreviewMouseLeftButtonDownイベントで)、ブラウザの通常の機能を模倣しているようです:

XAMLには次のTextBox発言があります。

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

分離コード:

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();
    }
}

1
アプリケーション内を移動するユーザーのために、TextBox.SelectAll()を内部に含むGotKeyboardFocusイベントを追加したい場合があります。ソリューションはPasswordBoxesでも機能します(PasswordBoxesはシールされたタイプであるため、拡張できません)。
デビッドシェレット

1

この拡張メソッドを試して、必要な動作を任意のTextBoxコントロールに追加します。私はまだそれを広範囲にテストしていませんが、それは私のニーズを満たしているようです。

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();
            }
        }
    }
}

1

私は多くの解決策を検索しましたが、selectallにいくつかの解決策を見つけましたが、問題は、テキストボックスからテキストの一部を選択した後に右クリックしてカット/コピーを行うと、テキストの一部を選択した場合でもすべて選択されます。ここでこれを修正することが解決策です。以下のコードをキーボード選択イベントに追加するだけです。これでうまくいきました。

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();
}

1

同じ問題がありました。VB.Netでは、次のように簡単に機能します。

VB XAML:

<TextBox x:Name="txtFilterFrequency" />

コードハインド:

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#(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);
}

私にとって最良の解決策、私はここにC#の翻訳を投稿しました:stackoverflow.com/a/48385409/3936440
ViRuSTriNiTy

私にとって、このアプローチではテキストを選択できないことがあります。BeginInvokeによる競合状態だと思います。
Vimes

ご指定ください。ディスパッチャーの優先順位は、デフォルトのアプリケーションで期待どおりに機能しています。あなたの状況はどうですか?説明どおり正確に試しましたか?あなたのソリューションで特別なことはありますか?
Nasenbaer

1

これは、最も簡単な解決策です。

グローバルハンドラーをアプリケーション(App.xaml.cs)に追加して完了します。ほんの数行のコードが必要になります。

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

    base.OnStartup(e);
}

したがって、EventManagerクラスを使用して、タイプ(TextBox)に対してグローバルイベントハンドラーを登録します。実際のハンドラーは非常に単純です:

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

ここをチェック:WPF TextBox SelectAll on Focus

それが役に立てば幸い。


1

Donnelle / Grokyのアプローチに関心があるが、最後の文字の右側(ただし内TextBox)をクリックして、入力したテキストの最後にキャレットを配置したい場合は、次の解決策を考え出しました。

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();
}

GetRoundedCharacterIndexFromPoint方法は以下から撮影されたこの記事。


1
正常に機能するが、ダブルクリックイベントがトリガーされない
Rodrigo Caballero

実際にはdoubleclickイベントに入りますが、OriginalSourceプロパティのタイプはTextBoxViewです。したがって、SelectAllTextメソッドは次のようになります。private static void SelectAllText(object sender、RoutedEventArgs e){var textBox = e.OriginalSource as TextBox; if(textBox!= null){textBox.SelectAll(); System.Diagnostics.Debug.WriteLine( "Selected ALL"); } else if(sender is TextBox){(sender as TextBox).SelectAll(); }
ロドリゴカバジェロ2014年

1

グーグルしてテストした後、私にはうまくいく簡単な解決策を見つけました。

Loadedコンテナーウィンドウのイベントにイベントハンドラーを追加する必要があります。

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

次に、RoutedEventHandler前のコードで参照されているハンドラーを作成する必要があります。

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

これで、イベントハンドラーのSelectAll()コマンドGotFocusを任意のTextBoxコントロールに個別に追加できます。

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

これでテキストがフォーカスされて選択されました!

Dr. WPFソリューション、MSDNフォーラムから改作


私はちょうど使用しました:private async void TBTime_GotFocus(object sender、RoutedEventArgs e){TextBox tb =(TextBox)e.OriginalSource; await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal、async()=> {tb.SelectAll();}); }
デビッドジョーンズ

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

ウィンドウに20個のテキストボックスがある場合、すべてのテキストボックスに対して3つのメソッドを作成しますか?このアプローチは良くありません。ここを見てみましょう:rachel53461.wordpress.com/2011/11/05/...
アレクサンドルDicu

0

これは私にはうまくいくようです。これは基本的に、以前のいくつかの投稿の要約です。これをコンストラクターのMainWindow.xaml.csファイルに挿入するだけです。1つはキーボード用、もう1つはマウス用の2つのハンドラーを作成し、両方のイベントを同じ関数にまとめHandleGotFocusEventます。これは、同じファイルのコンストラクターの直後に定義されています。

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();
}

素晴らしく簡単ですが、タイミングの問題があるようです-試行するたびに(マウスクリック)、すぐに再び選択が解除されます...?
T4NK3R 2016

0

mouseDownをオーバーライドし、ダブルクリック後にすべてを選択する簡単な方法は次のとおりです。

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();
    }
}

0

あなたのテキストボックスを収容しているコントロールのコンストラクタにこれを入れてみてください:

Loaded += (sender, e) =>
{
    MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    myTextBox.SelectAll();
}

これをウィンドウコンストラクターに配置すると、このアプローチは機能しません。
ViRuSTriNiTy 2018年

0

OnFocusマウスを離したときにテキストの選択を解除するイベントがある場合、通常はすべての選択を遅らせます。

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

-1

私はそれらすべてをテストしましたが、以下のみがうまくいきました:

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();
}

4
これは、ハッシュコードのわいせつな誤用でもあります。私はこれを読みます、リンク
RichK '13

3
そして、GetType().Name代わりに、isまたはasかなりハッキーです
RichK

-1

答えはたくさんあるようですが、承認されたものとして使用すべき方法は EditTextBoxGotCapture

次のコードを後ろに置きます:

private void EditTextBoxGotCapture(object sender, MouseEventArgs e)
{
    if (sender is TextBox tb)
    {
        tb.Select(0, tb.Text.Length);
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.