85

初めてウィンドウを開いたときに、WPFテキストボックスの文字列値の末尾にキャレット/カーソルの位置を設定しようとしています。ウィンドウが開いたときに、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>
4

10 に答える 10

117

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

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

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

NumberOfDigits.CaretIndex = NumberOfDigits.Text.Length;
于 2010-05-23T18:52:52.050 に答える
26

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

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

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>
于 2013-08-21T20:04:32.470 に答える
5

これは私のために働いた。私もMVVMパターンを使用しています。ただし、MMVMを使用する目的は、単体テストを可能にし、UIの更新を容易にすることです(緩く結合されています)。カーソルの位置を単体テストしているとは思わないので、この単純なタスクの背後にあるコードに頼ってもかまいません。

    public ExpeditingLogView()
    {
        InitializeComponent();

        this.Loaded += (sender, args) =>
        {                                
            Description.CaretIndex = Description.Text.Length;
            Description.ScrollToEnd();
            Description.Focus();
        };
    }
于 2017-06-09T14:04:36.777 に答える
3

複数行TextBox設定の場合はカーソルが足りません。これを試して:

NumberOfDigits.ScrollToEnd();
于 2016-09-26T11:41:34.510 に答える
3

WPFでは、行が十分に長い場合は、行の最後までスクロールすることも重要です。だから私は次の行を使用しています:

text_Box.Text = text;
text_Box.CaretIndex = text.Length;
text_Box.ScrollToHorizontalOffset(double.MaxValue);
// or you can use this - for me works also
// text_Box.ScrollToHorizontalOffset(text_Box.GetRectFromCharacterIndex(openFileDialog.FileName.Length).Right);

しかし、この注意を読んでください(私にとっては問題ありません-おそらくすでに修正されています): TextBox ScrollToHorizo​​ntalOffsetは、テキストが十分に長くなった後はスクロールしません

于 2019-11-08T19:58:25.030 に答える
3

@Louisソリューションはtextbox、テンプレートバインディング、または任意のタイプのレイジーバインディングまたはレイジー値の割り当てで使用された場合は機能しません

したがって、textboxたとえばDatagridセルでテンプレートとして使用する場合、そのソリューションを機能させるには小さな変更が必要になります。

そしてそれはテキスト変更イベントを購読しています

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

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

            _textBox = AssociatedObject as TextBox;

            if (_textBox == null)
            {
                return;
            }
            _textBox.GotFocus += TextBoxGotFocus;
            // to make it work with binding
            _textBox.TextChanged += TextBoxGotFocus;
        }

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

            base.OnDetaching();
        }

        private void TextBoxGotFocus(object sender, RoutedEventArgs routedEventArgs)
        {
            _textBox.CaretIndex = _textBox.Text.Length;
        }
    }
于 2020-05-12T05:11:27.747 に答える
2

ここでの答えはどれも私にはうまくいきませんでした。TextBoxのバインディングを使用しており、ウィンドウがポップアップした直後にキャレットを移動する必要があります。これは私のためにそれをしました:

public MyWindow()
{
    InitializeComponent();

    ContentRendered += (sender, args) =>
    {
        MyTextBox.CaretIndex = MyTextBox.Text.Length;
        MyTextBox.ScrollToEnd(); // not necessary for single line texts
        MyTextBox.Focus();
    };
}

Ceranskiの答えに似ています。Loadedイベントに追加する代わりに、に追加しContentRenderedます。

于 2019-12-18T08:45:08.383 に答える
0

いくつかの理由で私は使用しなければなりませんでした:

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => 
{
    textBox.CaretIndex = textBox.Text.Length;
    textBox.ScrollToEnd();
}));
于 2021-02-18T12:46:48.220 に答える
0

次の方法を試してください: https ://docs.microsoft.com/en-us/dotnet/desktop/wpf/controls/position-the-cursor-at-the-beginning-or-end-of-text?view = netframeworkdesktop -4.8

textBox.Select(2,0);
于 2021-05-14T12:06:57.247 に答える
0

ViewModelにバインドされた事前入力されたテキストボックスを使用してUserControl/Viewを作成したかったのですが、コントロールが開くと、フォーカスはテキストボックスと最後のカレット位置に自動的に設定されます。これが私がそれを機能させる唯一の方法でした:

public TextBoxDialogView()
{
    InitializeComponent();

    TextBox.GotKeyboardFocus += (sender, args) =>
    {
        TextBox.CaretIndex = TextBox.Text.Length;
    };
    _ = TextBox.Focus();
}

これまでのところうまく機能しているようです...

于 2021-07-08T13:22:57.410 に答える