How to bind SelectionStart Property of Text Box?

后端 未结 4 1114
北恋
北恋 2020-12-06 18:20

I use this:



but it always shows 0.<

相关标签:
4条回答
  • 2020-12-06 18:48

    I ran into this problem (SelectionStart and SelectionLength are not dependency properties) and decided to make a TextBox with bindable selection start and end:

    public class SelectionBindingTextBox : TextBox
    {
        public static readonly DependencyProperty BindableSelectionStartProperty =
            DependencyProperty.Register(
            "BindableSelectionStart",
            typeof(int),
            typeof(SelectionBindingTextBox),
            new PropertyMetadata(OnBindableSelectionStartChanged));
    
        public static readonly DependencyProperty BindableSelectionLengthProperty =
            DependencyProperty.Register(
            "BindableSelectionLength",
            typeof(int),
            typeof(SelectionBindingTextBox),
            new PropertyMetadata(OnBindableSelectionLengthChanged));
    
        private bool changeFromUI;
    
        public SelectionBindingTextBox() : base()
        {
            this.SelectionChanged += this.OnSelectionChanged;
        }
    
        public int BindableSelectionStart
        {
            get
            {
                return (int)this.GetValue(BindableSelectionStartProperty);
            }
    
            set
            {
                this.SetValue(BindableSelectionStartProperty, value);
            }
        }
    
        public int BindableSelectionLength
        {
            get
            {
                return (int)this.GetValue(BindableSelectionLengthProperty);
            }
    
            set
            {
                this.SetValue(BindableSelectionLengthProperty, value);
            }
        }
    
        private static void OnBindableSelectionStartChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            var textBox = dependencyObject as SelectionBindingTextBox;
    
            if (!textBox.changeFromUI)
            {
                int newValue = (int)args.NewValue;
                textBox.SelectionStart = newValue;
            }
            else
            {
                textBox.changeFromUI = false;
            }
        }
    
        private static void OnBindableSelectionLengthChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            var textBox = dependencyObject as SelectionBindingTextBox;
    
            if (!textBox.changeFromUI)
            {
                int newValue = (int)args.NewValue;
                textBox.SelectionLength = newValue;
            }
            else
            {
                textBox.changeFromUI = false;
            }
        }
    
        private void OnSelectionChanged(object sender, RoutedEventArgs e)
        {
            if (this.BindableSelectionStart != this.SelectionStart)
            {
                this.changeFromUI = true;
                this.BindableSelectionStart = this.SelectionStart;
            }
    
            if (this.BindableSelectionLength != this.SelectionLength)
            {
                this.changeFromUI = true;
                this.BindableSelectionLength = this.SelectionLength;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-06 18:51

    You cannot bind to SelectionStart because it is not a DependencyProperty.

    0 讨论(0)
  • 2020-12-06 18:54

    This could be an alternate solution:

    View:

    <TextBox Text="{Binding Text}">
        <i:Interaction.Triggers>
           <i:EventTrigger EventName="SelectionChanged">
               <mvvml:EventToCommand Command="{Binding TextBoxSelectionChangedCommand}" 
                                     PassEventArgsToCommand="True" />
           </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>
    

    ViewModel:

        #region TextBoxSelectionChangedCommand
        RelayCommand<RoutedEventArgs> _TextBoxSelectionChangedCommand = null;
        public ICommand TextBoxSelectionChangedCommand {
            get {
                if (_TextBoxSelectionChangedCommand == null) {
                    _TextBoxSelectionChangedCommand = new RelayCommand<RoutedEventArgs>((r) => TextBoxSelectionChanged(r), (r) => true);
                }
    
                return _TextBoxSelectionChangedCommand;
            }
        }
    
        protected virtual void TextBoxSelectionChanged(RoutedEventArgs _args) {
            YourCursorPositionVariable = (_args.OriginalSource as System.Windows.Controls.TextBox).SelectionStart;
        }
        #endregion
    

    I agree you has to cast TextBox component type in ViewModel and it's a kind of coupling, but create a custom component will impose to bind on a specific property as well.

    0 讨论(0)
  • 2020-12-06 19:01

    As far as I am aware, this feature has not been included in Silverlight 2.0.

    Read this article for a work-around solution.

    0 讨论(0)
提交回复
热议问题