Текстовая вставка неправильно работает при изменении значения базового свойства - PullRequest
2 голосов
/ 17 декабря 2010

См. Следующий пример:

<Window 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:src="clr-namespace:WpfApplication1"
  SizeToContent="WidthAndHeight">
  <Window.DataContext>
    <src:CodeName/>
  </Window.DataContext>
  <TextBox Text="{Binding Code, UpdateSourceTrigger=PropertyChanged}" />
</Window>

Imports System.ComponentModel
Public Class CodeName
  Implements INotifyPropertyChanged

  Private m_Code As String
  Public Property Code() As String
    Get
      Return m_Code
    End Get
    Set(ByVal value As String)
      If Not String.IsNullOrWhiteSpace(value) Then value = "_" & value
      m_Code = value
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Code"))
    End Set
  End Property

  Public Event PropertyChanged(ByVal sender As Object,
    ByVal e As PropertyChangedEventArgs) _
      Implements INotifyPropertyChanged.PropertyChanged
End Class

Как видите, я изменяю отредактированное значение так, что когда пользователь вводит текст в TextBox, оно обновляется, добавляя_ в его начало.

Что происходит, когда я набираю 123456789, результат в TextBox будет: _________987654321 не _________123456789, как ожидалось.

Что может быть аккуратным способом исправить это?
Я не хочу, чтобы весь мой код был загрязнен событиями KeyUp и т. Д., Перемещая курсор.
С другой стороны, я хочу, чтобы это было сделано вуровень сущности.

Примечание: моя «реальная» функция - это форматирование номера телефона с тире и т. д.

Ответы [ 2 ]

0 голосов
/ 17 декабря 2010
Public Class TextBoxBehavor
Public Shared Function GetMoveCaretOnTextChange(ByVal element As TextBox) As Boolean
  If element Is Nothing Then Throw New ArgumentNullException("element")
  Return element.GetValue(MoveCaretOnTextChangeProperty)
End Function
Public Shared Sub SetMoveCaretOnTextChange(ByVal element As TextBox, ByVal value As Boolean)
  If element Is Nothing Then Throw New ArgumentNullException("element")
  element.SetValue(MoveCaretOnTextChangeProperty, value)
End Sub
Public Shared ReadOnly MoveCaretOnTextChangeProperty As DependencyProperty =
  DependencyProperty.RegisterAttached("MoveCaretOnTextChange",
    GetType(Boolean), GetType(TextBoxBehavior),
    New FrameworkPropertyMetadata(
      New PropertyChangedCallback(AddressOf MoveCaretOnTextChange_PropertyChanged)))

Private Shared Sub MoveCaretOnTextChange_PropertyChanged(ByVal sender As Object,
  ByVal e As DependencyPropertyChangedEventArgs)
  Dim tb = DirectCast(sender, TextBox)
  Static tb_TextChanged As TextChangedEventHandler =
    Sub(obj, tcea)
      Dim textBox = DirectCast(obj, TextBox)
      textBox.CaretIndex = textBox.Text.Length
    End Sub

  If CBool(e.NewValue) Then
    AddHandler tb.TextChanged, tb_TextChanged
  Else
    RemoveHandler tb.TextChanged, tb_TextChanged
  End If
End Sub
End Class

Использование:

<TextBox src:TextBoxBehavior.MoveCaretOnTextChange="True"
  xmlns:src="clr-namespace:WpfApplication1" />
0 голосов
/ 17 декабря 2010

Я бы использовал событие textaged в текстовом поле, чтобы переместить курсор в конец, например:

 <TextBox Name="textBox1" Text="{Binding Code, UpdateSourceTrigger=PropertyChanged}" TextChanged="textChangedEventHandler"/>


Private Sub textChangedEventHandler(ByVal sender As Object, ByVal args As TextChangedEventArgs)
   textBox1.CaretIndex = textBox1.Text.Length
End Sub
...