2010-03-17 64 views
2

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

什么,我会真的喜欢做的事情是这样的:

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

基本上只是使用整个文本与一次性绑定SelectedText。但是,这是行不通的,因为SelectedText不是DependencyProperty。

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

任何想法,非常感谢!

回答

3

丹,

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

用法如下:

在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(); 
     } 
    } 
} 

运气好作品。

+0

我不认为子类化真的需要这个,但在TextBox的GotFocus事件上调用SelectAll()确实实现了我想要的数据绑定文本。我没有看到它是一个子类的真正原因,我只是在我的代码后面做了这个,如果我想要更多的MVVMish,它可以很容易地重构为Blend行为。谢谢! – 2010-03-18 16:02:23

2

因为在TextBox的GotFocus事件上调用SelectAll()做了诀窍,所以我要离开Jim的解决方案作为答案。

我实际上最终做出了一个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(); 
     } 
    } 
} 
+0

这是用于Silverlight的WPF吗?当我试图用类型扩展TriggerAction时,编译器抱怨说TriggerAction不是通用的,所以它不能接受类型。 – Trinition 2010-05-26 14:41:24

+0

这是用于Silverlight,我不确定Blend触发器和操作是否可用于WPF。你需要确保你从System.Windows.Interactivity.TriggerAction <>继承而不是System.Windows.TriggerAction。你将不得不从Blend SDK中引用DLL。 – 2010-05-26 20:37:17

1

只是想添加一个链接我发现有关此 - 这是一个fantastic discussion(阅读评论)上Be haviours vs subclassing vvs附属性...