Development Tip

캐럿 / 커서 위치를 문자열 값 WPF 텍스트 상자의 끝으로 설정

yourdevel 2020. 11. 14. 11:12
반응형

캐럿 / 커서 위치를 문자열 값 WPF 텍스트 상자의 끝으로 설정


처음으로 창을 열 때 캐럿 / 커서 위치를 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>

CaretIndex속성을 사용하여 캐럿 위치를 설정할 수 있습니다 TextBox. 이것은 DependencyProperty. 그럼에도 불구하고 다음과 같이 XAML에서 설정할 수 있습니다.

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

재산 CaretIndex 후에 설정하는 것을 기억하십시오 Text. 그렇지 않으면 작동하지 않습니다. 따라서 Text예제에서 like에 바인딩하면 작동하지 않을 것입니다 . 이 경우 다음과 같이 코드 숨김을 사용하십시오.

NumberOfDigits.CaretIndex = NumberOfDigits.Text.Length;

코드 숨김 상태이면서 재사용 가능하다는 이점이있는 Behavior를 만들 수도 있습니다.

텍스트 상자의 포커스 이벤트를 사용하는 간단한 동작 클래스의 예 :

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>

이것은 나를 위해 일했습니다. 또한 MVVM 패턴을 사용하고 있습니다. 그러나 MMVM을 사용하는 목적은 단위 테스트를 가능하게하고 UI (느슨하게 결합 된)를 더 쉽게 업데이트하는 것입니다. 나는 커서의 위치를 ​​단위 테스트하는 것을 보지 않기 때문에이 간단한 작업을 위해 뒤에있는 코드에 의지하는 것을 신경 쓰지 않는다.

    public ExpeditingLogView()
    {
        InitializeComponent();

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

텍스트 상자 (WinForms)가 세로 스크롤 막대가있는 여러 줄인 경우 다음을 시도 할 수 있습니다.

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

참고 : WPF에서 .ScrollToCaret ()은 TextBox의 멤버가 아닙니다.


여러 줄 TextBox설정 커서가 부족한 경우 . 이 시도:

NumberOfDigits.ScrollToEnd();

참고URL : https://stackoverflow.com/questions/2888907/set-the-caret-cursor-position-to-the-end-of-the-string-value-wpf-textbox

반응형