【问题标题】:Select and Copy text in WPF Textbox using MVVM使用 MVVM 在 WPF 文本框中选择和复制文本
【发布时间】:2013-08-05 14:22:13
【问题描述】:

我发现这个问题可以帮助我实现我想做的部分事情:MVVM- How can I select text in a textbox?

我的第一个问题是我有两个文本框,每个文本框都有一个“全选”按钮,但我不知道如何调整接受的答案以便我可以独立控制每个文本框。

另外,我想为每个添加一个“复制所选文本”按钮。

如何在坚持 MVVM 模式的同时做到这一点?

【问题讨论】:

    标签: c# wpf mvvm textbox clipboard


    【解决方案1】:

    您可以将两个按钮绑定到调用不同文本框上工作的不同命令,或者您可以使用 commandParameters 来区分要处理的内容。

    您可以通过创建 AttachedProperty 或仅制作自定义控件来跟进链接的帖子。您需要做的基本上是为文本选择创建一个可绑定的属性。 TextBox 的属性“SelectedText”听起来是个好主意,但如果您尝试在 WPF 中绑定到它,则会引发错误,因为它不是 DependencyProperty。属性必须是 DependencyProperty 才能绑定到它。

    因此,您创建一个,例如将 IsTextSelected 作为布尔值,当它发生变化时,您的 AttachedProperty 或自定义控件会处理它并执行 SelectAll() 或 SelectedText=Text;

    如果只做一个项目,我建议使用 AttachedProperty。但是,您要求自定义控件,我认为如果对一种类型的控件进行多项功能改进时应该使用自定义控件,其中它们不能在不同类型上重复使用。

    public class SmartTextBox : TextBox
    {
        public static readonly DependencyProperty IsSelectedTextProperty = DependencyProperty.RegisterAttached("IsSelectedText",
            typeof(bool), typeof(SmartTextBox), new FrameworkPropertyMetadata(false, OnIsSelectedChanged));
    
        public bool IsSelectedText
        {
            get { return (bool)GetValue(IsSelectedTextProperty); }
            set { SetValue(IsSelectedTextProperty, value); }
        }
    
        private static void OnIsSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            SmartTextBox textbox = sender as SmartTextBox;
            if ((bool)e.NewValue)
            {
                textbox.Focus();
                textbox.SelectAll();
            }
        }
    }
    

    用法:视图模型

    • 注意 1 我不会对 set 期间的值是否相同进行 IF,以便您可以随时强制执行,而不是跟踪用户所做的事情。
    • Note2 创建多个属性,IsSelectedUsername、IsSelectedFilepath 等,并绑定它们。每个 SmartTextBox 都绑定到一个,并将处理一个发生变化的。

      public bool IsSelectedText
      {
          get { return isSelectedText; }
          set
          {
              isSelectedText = value;
              RaisePropertyChanged("IsSelectedText");
          }
      }
      
      private void SelectAllExecute()
      {
          IsSelectedText = true;
      }
      

    用法:XAML

    xmlns:custom="clr-namespace:xyz.View.Controls"
    
            <custom:SmartTextBox Text="{Binding Path=MyText}" 
                                 IsSelectedText="{Binding Path=IsSelectedText}"/>
    

    检索选定的文本,您需要向自定义控件添加一个可以绑定到的新依赖项属性以及控件更新它的方法。我选择控件何时离开焦点而不是更改选择,因为我希望用户在我需要知道所选文本之前执行诸如单击按钮之类的操作。

        public static readonly DependencyProperty SelectedText2Property = DependencyProperty.RegisterAttached("SelectedText2",
            typeof(string), typeof(SmartTextBox), new PropertyMetadata(""));
    
        public string SelectedText2
        {
            get { return (string)GetValue(SelectedText2Property); }
            set { SetValue(SelectedText2Property, value); }
        }
    
        protected override void OnLostFocus(RoutedEventArgs e)
        {
            SelectedText2 = this.SelectedText;
            base.OnLostFocus(e);
        }
    

    XAML 现在已绑定:

            <custom:SmartTextBox Text="{Binding Path=MyText}" 
                                 SelectedText2="{Binding Path=TheSelectedText, Mode=OneWayToSource}"
                                 IsSelectedText="{Binding Path=IsSelectedText}"/>
    

    ViewModel 有一个哑属性(无需引发更改事件,因为它是 OneWayToSource)

    public string TheSelectedText { get; set; }
    

    你可以做的任何地方

    Console.WriteLine(TheSelectedText);
    

    【讨论】:

    • 如果我正确理解了您的答案,我喜欢扩展 Textbox 并实现某种 SelectedText 属性的自定义控件的想法。你能提供任何链接或代码让我这样做吗?
    • 添加了自定义控件的完整而基本的实现。请务必记下 Note2,以便按照您的具体要求独立完成。
    • 太棒了!它运行良好;谢谢你的笔记。如何检索选定的文本?
    • @Andy 添加了检索。如果这已为您完成,请标记为完成。我认为这涵盖了有关该主题的所有内容,其他任何内容都将是一个新主题。再说一次,我想,你可以回复。
    • 您的假设完全正确!我不能要求更多。非常感谢!
    猜你喜欢
    • 2011-06-02
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多