2

コントロールが最初にロードされたときに、TextBox内のすべてのテキストを選択するための最良の方法を見つけようとしています。MVVMパターンを使用しているので、TextBoxのTextプロパティをViewModelの文字列に双方向でバインドしています。このTextBoxを使用して、すでに名前が付けられているものの「名前を変更」しているので、コントロールの読み込み時に古い名前を選択して、簡単に削除して名前を変更できるようにします。最初のテキスト(古い名前)は、ViewModelに設定することで入力され、データバインディングが完了した後、TextBoxに反映されます。

私が本当にやりたいのは次のようなものです。

<TextBox x:Name="NameTextBox" Text="{Binding NameViewModelProperty, Mode=TwoWay}" SelectedText="{Binding NameViewModelProperty, Mode=OneTime}" />

基本的には、テキスト全体をOneTimeバインディングのSelectedTextとして使用します。ただし、SelectedTextはDependencyPropertyではないため、これは機能しません。

私は自分のビューのコードビハインドに選択コードを追加することに完全に反対しているわけではありませんが、その場合の私の問題は、最初のテキストバインディングがいつ完了したかを判断することです。TextBoxは常に空で開始されるため、コンストラクターで実行することはできません。TextChangedイベントは、ユーザーが新しいテキストを入力したときにのみ発生するように見えます。ViewModelの最初のバインドからテキストが変更されたときは発生しません。

どんなアイデアでも大歓迎です!

4

3 に答える 3

3

ダン、

この機能を提供する非常に単純な派生クラスTextBoxExを作成しました。TextBoxExクラスはTextBoxから派生し、XAMLですべてのTextBoxを参照できます。呼び出すメソッドはありません。フォーカスイベントをリッスンし、独自のテキストを選択するだけです。とてもシンプルです。

使用法は次のとおりです。

XAMLで、以下にリストされているTextBoxExクラスを実装するアセンブリを参照し、必要な数のTextBoxEx要素を追加します。以下の例では、データバインディングを使用してユーザー名を表示しています。

<UserControl x:Class="MyApp.MainPage"
    xmlns="http://schemas.microsoft.com/client/2007"     
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     
    xmlns:c="clr-namespace:ClassLibrary;assembly=ClassLibrary"  
>  
.     
.     
.     
<c:TextBoxEx x:Name="NameTextBox" Text="{Binding NameViewModelProperty, Mode=TwoWay}" Width="120" />

以下のこのコードはSilverlight3で機能します。

using System.Windows;
using System.Windows.Controls;

namespace ClassLibrary
{
    // This TextBox derived class selects all text when it receives focus
    public class TextBoxEx : TextBox
    {
        public TextBoxEx()
        {
            base.GotFocus += OnGotFocus;
        }

        private void OnGotFocus(object sender, RoutedEventArgs e)
        {
            base.SelectAll();
        }
    }
}

幸運を。

于 2010-03-18T03:27:01.470 に答える
2

SelectAll()TextBoxのGotFocusイベントを呼び出すとうまくいったので、Jimのソリューションを答えとして残しておきます。

私は実際に、TextBoxをサブクラス化したり、コードビハインドで実行したりする代わりに、BlendTriggerActionとEventTriggerを作成してこれを実行することになりました。動作ロジックをカプセル化したままにして、XAMLで既存のTextBoxに宣言的に追加できるのは本当に簡単で素晴らしいことです。

他の誰かがこのスレッドに出くわして興味がある場合に備えて、これを投稿するだけです。

XAML:

<TextBox x:Name="NameTextBox" Text="{Binding NameViewModelProperty, Mode=TwoWay}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="GotFocus">
            <local:SelectAllAction/>
        </i:EventTrigger>
     </i:Interaction.Triggers>
</TextBox>

C#

public class SelectAllAction : TriggerAction<TextBox>
{
    protected override void Invoke(object parameter)
    {
        if (this.AssociatedObject != null)
        {
            this.AssociatedObject.SelectAll();
        }
    }
}
于 2010-03-18T16:30:42.640 に答える
1

これに関連して私が見つけたリンクを追加したいだけです-これは、動作とサブクラス化vs添付プロパティに関する素晴らしい議論(コメントを読む)です...

于 2010-07-13T19:32:13.130 に答える