【问题标题】:How to bind SelectionStart Property of Text Box?如何绑定文本框的 SelectionStart 属性?
【发布时间】:2010-11-13 14:54:20
【问题描述】:

我用这个:

<TextBox x:Name="Test"/>
<TextBlock Text="{Binding SelectionStart, ElementName=Test}"/>

但它总是显示 0。
我该如何治疗?
谢谢。

【问题讨论】:

    标签: silverlight binding textbox selection


    【解决方案1】:

    据我所知,Silverlight 2.0 中并未包含此功能。

    阅读this 文章以了解变通解决方案。

    【讨论】:

    • silverlight 3 中已添加此功能。在此示例中效果很好: 但不适用于我的。我不喜欢那篇文章,这种风格实际上扼杀了装订的所有美感。
    【解决方案2】:

    这可能是另一种解决方案:

    查看:

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

    视图模型:

        #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
    

    我同意您必须在 ViewModel 中强制转换 TextBox 组件类型,这是一种耦合,但创建自定义组件也会强制绑定到特定属性。

    【讨论】:

      【解决方案3】:

      我遇到了这个问题(SelectionStart 和 SelectionLength 不是依赖属性)并决定制作一个具有可绑定选择开始和结束的 TextBox:

      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;
              }
          }
      }
      

      【讨论】:

      • 似乎是可用的最佳解决方案,但这不适用于双向数据绑定。
      【解决方案4】:

      您不能绑定到 SelectionStart,因为它不是 DependencyProperty。

      【讨论】:

      • 有没有办法找出给定控件上的哪些属性是 DependencyProperties,哪些不是?
      • 最快的方法是使用 Visual Studio 的 Intellisense。例如,假设您想查看 TextBox 的所有依赖属性。只需键入文本框。并且智能感知会向你展示它的所有依赖属性。
      猜你喜欢
      • 2011-02-06
      • 2011-09-03
      • 2012-06-24
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      相关资源
      最近更新 更多