2010-05-22 8 views
54

처음으로 창을 열면 내 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> 

답변

76

당신은 TextBoxCaretIndex 속성을 사용하여 캐럿 위치를 설정할 수 있습니다. 이 번호는 DependencyProperty이 아닙니다. 그럼에도 불구하고, 여전히이 같은 XAML에서 설정할 수 있습니다

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

Text 재산 후 CaretIndex을 설정하는 것을 기억하십시오 그렇지 않으면이 작동하지 않습니다. 따라서 예를 들어 Text에 바인딩하면 작동하지 않습니다. 이 경우 간단히 코드 숨김을 사용하십시오.

NumberOfDigits.CaretIndex = NumberOfDigits.Text.Length; 
+2

예, CaretIndex에 바인딩하려고했으나 실패했습니다. Window Loaded Event의 코드 숨김에 코드를 추가하는 것이 효과적입니다. 감사합니다. . – Zamboni

16

코드 숨김을 유지하면서 재사용 할 수있는 동작을 만들 수도 있습니다. 텍스트 상자의 포커스 이벤트를 사용하여 간단한 행동 클래스의

예 :

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

이것은 최고의 솔루션입니다. 수동으로 커서를 설정하는 것은 엉덩이의 고통입니다. – Darkhydro

2

경우 텍스트 상자 (WinForms)는 여러 줄의 세로 스크롤 막대를 가지고 있습니다.

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

참고 : WPF.ScrollToC aret()는 TextBox의 멤버가 아닙니다.

1

멀티 라인의 경우 TextBox 설정 커서가 충분하지 않습니다. 시험해보기 :

NumberOfDigits.ScrollToEnd(); 
+0

코드 만 대답하면 좋은 대답이 아니며 몇 줄을 추가하여 문제의 원인과 코드가 해결 된 이유를 설명하십시오. – MikeT

2

이것은 저에게 효과적입니다. 또한 MVVM 패턴을 사용하고 있습니다. 그러나 MMVM을 사용하려는 나의 목적은 단위 테스트를 가능하게하고 UI (느슨하게 결합 된)를 쉽게 업데이트 할 수있게하는 것입니다. 나는 커서의 위치를 ​​테스트하는 단위를 볼 수 없으므로이 간단한 작업을 위해 코드를 사용하는 것에 신경 쓰지 않아도된다.

public ExpeditingLogView() 
    { 
     InitializeComponent(); 

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