【问题标题】:Select the Initial Text in a Silverlight TextBox在 Silverlight 文本框中选择初始文本
【发布时间】:2011-01-28 17:21:10
【问题描述】:

我试图找出在第一次加载控件时选择 TextBox 中所有文本的最佳方法。我正在使用 MVVM 模式,因此我将 TextBox 的 Text 属性使用双向绑定到我的 ViewModel 上的字符串。我正在使用这个 TextBox 来“重命名”已经有名称的东西,所以我想在控件加载时选择旧名称,以便可以轻松地删除和重命名它。初始文本(旧名称)通过在我的 ViewModel 中设置来填充,然后在数据绑定完成后反映在 TextBox 中。

真正想做的是这样的:

<TextBox x:Name="NameTextBox" Text="{Binding NameViewModelProperty, Mode=TwoWay}" SelectedText="{Binding NameViewModelProperty, Mode=OneTime}" />

基本上只是将整个文本用作具有 OneTime 绑定的 SelectedText。但是,这不起作用,因为 SelectedText 不是 DependencyProperty。

我并不完全反对在视图的代码隐藏中添加选择代码,但在这种情况下,我的问题是确定初始文本绑定何时完成。 TextBox 总是开始为空,因此不能在构造函数中完成。 TextChanged 事件似乎只在用户输入新文本时触发,而不是在文本从 ViewModel 的初始绑定发生更改时触发。

非常感谢任何想法!

【问题讨论】:

    标签: silverlight data-binding textbox viewmodel selectedtext


    【解决方案1】:

    丹,

    我编写了一个非常简单的派生类 TextBoxEx,它提供了这个功能。 TextBoxEx 类派生自 TextBox,并且可以在 XAML 中为任何和所有 TextBox 引用。没有可调用的方法。它只是监听焦点事件并选择它自己的文本。很简单。

    用法如下:

    在 XAML 中,引用实现下面列出的 TextBoxEx 类的程序集,并根据需要添加尽可能多的 TextBoxEx 元素。下面的示例使用数据绑定来显示用户名。

    <UserControl x:Class="MyApp.MainPage"
        xmlns="http://schemas.microsoft.com/client/2007"     
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     
        xmlns:c="clr-namespace:ClassLibrary;assembly=ClassLibrary"  
    >  
    .     
    .     
    .     
    <c:TextBoxEx x:Name="NameTextBox" Text="{Binding NameViewModelProperty, Mode=TwoWay}" Width="120" />
    

    以下代码适用于 Silverlight 3。

    using System.Windows;
    using System.Windows.Controls;
    
    namespace ClassLibrary
    {
        // This TextBox derived class selects all text when it receives focus
        public class TextBoxEx : TextBox
        {
            public TextBoxEx()
            {
                base.GotFocus += OnGotFocus;
            }
    
            private void OnGotFocus(object sender, RoutedEventArgs e)
            {
                base.SelectAll();
            }
        }
    }
    

    祝你好运。

    【讨论】:

    • 我不相信子类化对于这个真的是必要的,但是在 TextBox 的 GotFocus 事件上调用 SelectAll() 确实实现了我想要的,即使是数据绑定文本。我看不出它是一个子类的任何真正原因,我只是在我的代码隐藏中做到了这一点,如果我想获得更多的 MVVMish,它可以很容易地重构为 Blend 行为。谢谢!
    【解决方案2】:

    我将 Jim 的解决方案作为答案,因为在 TextBox 的 GotFocus 事件上调用 SelectAll() 可以解决问题。

    我实际上最终制作了一个 Blend TriggerAction 和一个 EventTrigger 来执行此操作,而不是继承 TextBox 或在代码隐藏中执行它。能够将行为逻辑封装起来,只需在 XAML 中以声明方式将其添加到现有的 TextBox 中,这真的很简单,而且很好。

    只是发布这个以防其他人遇到这个线程并感兴趣:

    XAML:

    <TextBox x:Name="NameTextBox" Text="{Binding NameViewModelProperty, Mode=TwoWay}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="GotFocus">
                <local:SelectAllAction/>
            </i:EventTrigger>
         </i:Interaction.Triggers>
    </TextBox>
    

    C#

    public class SelectAllAction : TriggerAction<TextBox>
    {
        protected override void Invoke(object parameter)
        {
            if (this.AssociatedObject != null)
            {
                this.AssociatedObject.SelectAll();
            }
        }
    }
    

    【讨论】:

    • 这是给 Silverlight 的 WPF 的吗?当我尝试使用类型扩展 TriggerAction 时,编译器抱怨 TriggerAction 不是通用的,因此它不能接受类型。
    • 这适用于 Silveright,我不确定 Blend 触发器和操作是否可用于 WPF。您需要确保您继承自 System.Windows.Interactivity.TriggerAction 而不是 System.Windows.TriggerAction。您必须从 Blend SDK 中引用 DLL。
    【解决方案3】:

    只想添加一个我发现的与此相关的链接 - 这是关于行为与子类化 vvs 附加属性的fantastic discussion(阅读 cmets)...

    【讨论】:

      猜你喜欢
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 2011-02-05
      相关资源
      最近更新 更多