2

我试图找出在第一次加载控件时选择 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 的初始绑定更改时触发。

任何想法都非常感谢!

4

3 回答 3

3

担,

我编写了一个非常简单的派生类 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();
        }
    }
}

祝你好运。

于 2010-03-18T03:27:01.470 回答
2

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

实际上,我最终制作了一个 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();
        }
    }
}
于 2010-03-18T16:30:42.640 回答
1

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

于 2010-07-13T19:32:13.130 回答