web-dev-qa-db-ja.com

キャレット/カーソルの位置を文字列値WPFテキストボックスの最後に設定します

キャレット/カーソルの位置を、ウィンドウを初めて開いたときに、WPFテキストボックスの文字列値のendに設定しようとしています。 FocusManagerを使用して、ウィンドウが開いたときにテキストボックスにフォーカスを設定します。

何も機能しないようです。何か案は?

注、MVVMパターンを使用しており、コードからXAMLの一部のみを含めています。

<Window 
    FocusManager.FocusedElement="{Binding ElementName=NumberOfDigits}"
    Height="400" Width="800">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <TextBox Grid.Column="0" Grid.Row="0" 
                 x:Name="NumberOfDigits"
                 IsReadOnly="{Binding Path=IsRunning, Mode=TwoWay}"
                 VerticalContentAlignment="Center"
                 Text="{Binding Path=Digits, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        <Button Grid.Column="0" Grid.Row="1" 
                 Margin="10,0,10,0"
                 IsDefault="True"
                 Content="Start" 
                 Command="{Binding StartCommand}"/>
    </Grid>
 </Window>
65
Zamboni

CaretIndexTextBoxプロパティを使用して、キャレットの位置を設定できます。これはDependencyPropertyではないことに注意してください。それでも、XAMLで次のように設定できます。

<TextBox Text="123" CaretIndex="{x:Static System:Int32.MaxValue}" />

CaretIndexafterTextプロパティを設定することを忘れないでください。そうしないと機能しません。したがって、あなたの例のようにTextにバインドした場合、おそらく動作しません。その場合は、このようなコードビハインドを使用します。

NumberOfDigits.CaretIndex = NumberOfDigits.Text.Length;
91
wpfwannabe

また、ビヘイビアを作成することもできます。このビヘイビアは、コードビハインドのままでありながら、再利用できるという利点があります。

テキストボックスのフォーカスイベントを使用した単純な動作クラスの例:

class PutCursorAtEndTextBoxBehavior: Behavior<UIElement>
{
   private TextBox _textBox;

   protected override void OnAttached()
   {
        base.OnAttached();

        _textBox = AssociatedObject as TextBox;

        if (_textBox == null)
        {
            return;
        }
        _textBox.GotFocus += TextBoxGotFocus;
   }

    protected override void OnDetaching()
    {
        if (_textBox == null)
        {
            return;
        }
        _textBox.GotFocus -= TextBoxGotFocus;

        base.OnDetaching();
    }

    private void TextBoxGotFocus(object sender, RoutedEventArgs routedEventArgs)
    {
        _textBox.CaretIndex = _textBox.Text.Length;
    }
}    

次に、XAMLで、次のような動作をアタッチします。

    <TextBox x:Name="MyTextBox" Text="{Binding Value}">
        <i:Interaction.Behaviors>
            <behaviors:PutCursorAtEndTextBoxBehavior/>
        </i:Interaction.Behaviors>
    </TextBox>
20
Louis

これは私のために働いた。 MVVMパターンも使用しています。ただし、MMVMを使用する目的は、単体テストを可能にし、UIの更新(疎結合)を簡単にすることです。私はカーソルの位置を単体でテストしているのを見ないので、この単純なタスクのためにコードビハインドに頼ることを気にしません。

    public ExpeditingLogView()
    {
        InitializeComponent();

        this.Loaded += (sender, args) =>
        {                                
            Description.CaretIndex = Description.Text.Length;
            Description.ScrollToEnd();
            Description.Focus();
        };
    }
4

テキストボックス(WinForms)が垂直スクロールバーのある複数行の場合、これを試すことができます:

textbox1.Select(textbox1.Text.Length-1, 1);
textbox1.ScrollToCaret();

注:WPFでは、ScrollToCaret()はTextBoxのメンバーではありません。

3
molbalga

複数行TextBoxの場合、カーソルを設定するだけでは不十分です。これを試して:

NumberOfDigits.ScrollToEnd();
1
andreikashin