如何绑定到CaretIndex又名文本框的光标位置

嗨,我正在尝试绑定到不是DependencyPropertyTextBox.CaretIndex属性,所以我创建了一个Behavior ,但它没有按预期工作。

期望(专注时)

  • 默认= 0
  • 如果我在视图中更改了值,它应该更改viewmodel中的值
  • 如果我更改了viewmodel中的值,它应该更改我视图中的值

目前的行为

  • 当窗口打开时,viewmodel值被调用

代码隐藏

 public class TextBoxBehavior : DependencyObject { public static readonly DependencyProperty CursorPositionProperty = DependencyProperty.Register( "CursorPosition", typeof(int), typeof(TextBoxBehavior), new FrameworkPropertyMetadata( default(int), new PropertyChangedCallback(CursorPositionChanged))); public static void SetCursorPosition(DependencyObject dependencyObject, int i) { // breakpoint get never called dependencyObject.SetValue(CursorPositionProperty, i); } public static int GetCursorPosition(DependencyObject dependencyObject) { // breakpoint get never called return (int)dependencyObject.GetValue(CursorPositionProperty); } private static void CursorPositionChanged( DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) { // breakpoint get never called //var textBox = dependencyObject as TextBox; //if (textBox == null) return; } } 

XAML

  

更多的信息

我认为这里有一些问题,因为我需要从之前从未需要的DependencyObject派生它,因为CursorPositionProperty已经是DependencyProperty ,所以这应该足够了。 我还认为我需要在我的Behavior使用一些事件来正确设置我的CursorPositionProperty ,但我不知道哪个。

与我的行为斗争后,我可以为您提供99%的工作解决方案

行为

 using System.Windows; using System.Windows.Controls; using System.Windows.Data; namespace WpfMVVMTextBoxCursorPosition { public class TextBoxCursorPositionBehavior : DependencyObject { public static void SetCursorPosition(DependencyObject dependencyObject, int i) { dependencyObject.SetValue(CursorPositionProperty, i); } public static int GetCursorPosition(DependencyObject dependencyObject) { return (int)dependencyObject.GetValue(CursorPositionProperty); } public static readonly DependencyProperty CursorPositionProperty = DependencyProperty.Register("CursorPosition" , typeof(int) , typeof(TextBoxCursorPositionBehavior) , new FrameworkPropertyMetadata(default(int)) { BindsTwoWayByDefault = true ,DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged } ); public static readonly DependencyProperty TrackCaretIndexProperty = DependencyProperty.RegisterAttached( "TrackCaretIndex", typeof(bool), typeof(TextBoxCursorPositionBehavior), new UIPropertyMetadata(false , OnTrackCaretIndex)); public static void SetTrackCaretIndex(DependencyObject dependencyObject, bool i) { dependencyObject.SetValue(TrackCaretIndexProperty, i); } public static bool GetTrackCaretIndex(DependencyObject dependencyObject) { return (bool)dependencyObject.GetValue(TrackCaretIndexProperty); } private static void OnTrackCaretIndex(DependencyObject dependency, DependencyPropertyChangedEventArgs e) { var textbox = dependency as TextBox; if (textbox == null) return; bool oldValue = (bool)e.OldValue; bool newValue = (bool)e.NewValue; if (!oldValue && newValue) // If changed from false to true { textbox.SelectionChanged += OnSelectionChanged; } else if (oldValue && !newValue) // If changed from true to false { textbox.SelectionChanged -= OnSelectionChanged; } } private static void OnSelectionChanged(object sender, RoutedEventArgs e) { var textbox = sender as TextBox; if (textbox != null) SetCursorPosition(textbox, textbox.CaretIndex); // dies line does nothing } } } 

XAML

    

只是因为我不知道为什么它不起作用=> BindsTwoWayByDefault = true 。 据我所知,它对绑定没有影响因为我需要在XAML中设置绑定模式

正如您所说, TextBox.CaretIndex属性 不是 DependencyProperty ,因此您无法将数据绑定到它。 即使使用自己的DependencyProperty ,它也无法正常工作……当TextBox.CaretIndex属性发生变化时,您会如何获得通知?

我遇到了类似的问题,对我来说最简单的解决方案是从TextBoxinheritance并添加DependencyProperty。 所以它看起来像这样:

 namespace UI.Controls { public class MyTextBox : TextBox { public static readonly DependencyProperty CaretPositionProperty = DependencyProperty.Register("CaretPosition", typeof(int), typeof(MyTextBox), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnCaretPositionChanged)); public int CaretPosition { get { return (int)GetValue(CaretPositionProperty); } set { SetValue(CaretPositionProperty, value); } } public MyTextBox() { SelectionChanged += (s, e) => CaretPosition = CaretIndex; } private static void OnCaretPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { (d as MyTextBox).CaretIndex = (int)e.NewValue; } } } 

……在我的XAML中:

 xmlns:controls="clr-namespace:IU.Controls" ...  

…当然,View Model中的CaretPosition属性。 如果您不打算将View Model绑定到其他文本编辑控件,这可能就足够了,如果是 – 您可能需要另一个解决方案。