2010-03-17 58 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附屬性...