更改基础属性值时,TextBox 插入符会出错

发布于 2024-10-08 12:46:37 字数 1405 浏览 0 评论 0原文

请参阅以下示例:

<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 等事件移动插入符号弄脏。
另一方面,我确实希望这在实体级别完成。

注意:我的“现实生活”功能是用破折号等格式化电话号码。

See the following example:

<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

As you can see, I am changing the edited value so that when the user enters text in the TextBox, it's updated adding a _ to its beginning.

What happens is, that when I type 123456789 the result in the TextBox is: _________987654321 not _________123456789 as expected.

What could be a neat way to fix it?
I don't want to my my whole code dirty with KeyUp etc. events moving the caret around.
In the other hand, I do want this to be done at the entity level.

Note: my 'real-life' function is formatting a phone-number with dashes, and more.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雪落纷纷 2024-10-15 12:46:37

我将使用文本框的 textchanged 事件将插入符号移动到末尾,如下所示:

 <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

I would use the textchanged event of the textbox to move the caret to the end, like this:

 <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
无风消散 2024-10-15 12:46:37
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" />
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

Usage:

<TextBox src:TextBoxBehavior.MoveCaretOnTextChange="True"
  xmlns:src="clr-namespace:WpfApplication1" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文