如何绑定到 CaretIndex 又名文本框的光标位置 [英] How to Bind to CaretIndex aka curser position of an Textbox

查看:11
本文介绍了如何绑定到 CaretIndex 又名文本框的光标位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Hi I'm trying to bind to the TextBox.CaretIndex property which isn't a DependencyProperty, so I created a Behavior, but it doesn't work as expected.

期望(专注时)

  • 默认 = 0
  • 如果我更改我的 view 中的值,它应该更改我的 viewmodel
  • 中的值
  • 如果我更改 viewmodel 中的值,它应该会更改 view
  • 中的值
  • default = 0
  • if I change the value in my view it should change the value in my viewmodel
  • if I change the value in my viewmodel it should change the value in my view

当前行为

  • 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

<TextBox Text="{Binding TextTemplate,UpdateSourceTrigger=PropertyChanged}"
         local:TextBoxBehavior.CursorPosition="{Binding CursorPosition}"/>

更多信息

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

I think there is something really wrong here because I need to derive it from DependencyObject which was never needed before, because CursorPositionProperty is already a DependencyProperty, so this should be enough. I also think I need to use some events in my Behavior to set my CursorPositionProperty correctly, but I don't know which.

推荐答案

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

After fighting with my Behavior i can present you a 99% working solution

行为

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

    <TextBox Height="50" VerticalAlignment="Top"
             Name="TestTextBox"
             Text="{Binding MyText}"
             vm:TextBoxCursorPositionBehavior.TrackCaretIndex="True"
             vm:TextBoxCursorPositionBehavior.CursorPosition="{Binding CursorPosition,Mode=TwoWay}"/>

    <TextBlock Height="50" Text="{Binding CursorPosition}"/>

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

there is just on thing i don't know why it doesn't work => BindsTwoWayByDefault = true. it has no effect on the binding as far as i can tell you because of this i need to set the binding mode explicit in XAML

这篇关于如何绑定到 CaretIndex 又名文本框的光标位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆