2010-05-02 76 views
4

我有一個簡單的WM7頁面,其中包含TextBox。此外,我將EventToCommand(a RelayCommand<string>)分配給此TextBox,對TextChanged事件作出反應。爲了測試pourposes,我在頁面的代碼中添加了其他方法TextBox_TextChanged。命令和TextBox_TextChanged都用文本框內容打印消息框。MVVM Light太快:)

TextBox的初始值是"ABC"。然後按D和:

  1. TextBox_TextChanged打印ABCD
  2. 該命令打印ABC。 D缺失。

爲什麼命令如此之快?

命令聲明:

public RelayCommand<string> TextChanged {get; private set;} 

命令初始化:

TextChanged = new RelayCommand<string>((s) => MessageBox.Show(s)); 

命令綁定:

<TextBox x:Name="SearchTextBox" Margin="10,0" TextWrapping="Wrap" Text="{Binding SearchString, Mode=TwoWay}" FontStyle="Italic" TextChanged="SearchTextBox_TextChanged" > 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="TextChanged"> 
      <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding TextChanged, Mode=OneWay}" CommandParameter="{Binding Text, ElementName=SearchTextBox}"/> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
</TextBox> 
+0

你可以發佈你的代碼嗎?沒有看到它們是如何結合在一起的,很難確定地知道。 – Oded 2010-05-02 10:08:32

+0

這裏有問題嗎? – 2010-05-02 10:27:16

+0

作者:WM7你的意思是Windows Phone 7? – 2010-05-02 10:54:57

回答

6

我無法重現此問題。我曾嘗試使用EventToCommand和行爲(它只是監聽TextChanged事件)。

沒有看到代碼我懷疑這可能與您如何獲得搜索框的文本或其他地方的邏輯錯誤有關。

這是我如何使用EventToCommand一個片段:

<TextBox Name="SearchTextBox"> 
    <i:Interaction.Triggers> 
    <i:EventTrigger EventName="TextChanged"> 
     <cmd:EventToCommand Command="{Binding TestTextChangedCommand,Mode=OneWay}" CommandParameter="{Binding Path=Text, ElementName=SearchTextBox}"/> 
    </i:EventTrigger> 
    <i:Interaction.Triggers> 
</TextBox> 

在視圖模型

m_TestTextChangedCommand = new RelayCommand<string>(val => System.Diagnostics.Debug.WriteLine(val)); 

正如你可以看到我用了一個commandparameter傳遞文本框的視圖模型的價值。通過這種方式,viewmodel不必知道文本框就可以獲取文本值。

這種方法另一種方法是使用行爲和雙向綁定更新的屬性:

<TextBox Name="SearchTextBox" Text="{Binding TextInViewModel, Mode=TwoWay}" > 
    <i:Interaction.Behaviors> 
    <sc:UpdateOnTextChangedBehavior/> 
    </i:Interaction.Behaviors> 
</TextBox> 

UpdateOnTextChangedBehavior類:

public class UpdateOnTextChangedBehavior : Behavior<TextBox> 
    { 
     protected override void OnAttached() 
     { 
      base.OnAttached(); 

      this.AssociatedObject.TextChanged += 
       new TextChangedEventHandler(AssociatedObject_TextChanged); 
     } 

     void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e) 
     { 
      System.Diagnostics.Debug.WriteLine(((TextBox)sender).Text); 
      BindingExpression binding = 
       this.AssociatedObject.GetBindingExpression(TextBox.TextProperty); 
      if (binding != null) 
      { 
       binding.UpdateSource(); 
      } 
     } 

     protected override void OnDetaching() 
     { 
      base.OnDetaching(); 

      this.AssociatedObject.TextChanged -= 
       new TextChangedEventHandler(AssociatedObject_TextChanged); 
     } 
    } 

什麼上面所做的是模擬天生的桌面WPF的行爲BindingUpdateSourceTrigger=PropertyChanged,這在Silverlight中不存在。那麼會發生什麼,只要你輸入文本框TextInViewModel屬性就會得到更新。這個屬性並不是一個DependencyProperty,它可能只是一個正常的CLR屬性。

+0

謝謝!它像一個魅力,它幫助了我很多 – J4N 2011-11-28 14:19:00

0

一些代碼,我起訴(類似於你的命令爲例):

命令聲明:

public RelayCommand<string> TextChanged {get; private set;} 

命令初始化:

TextChanged = new RelayCommand<string>((s) => MessageBox.Show(s)); 

命令綁定:

<TextBox x:Name="SearchTextBox" Margin="10,0" TextWrapping="Wrap" Text="{Binding SearchString, Mode=TwoWay}" FontStyle="Italic" TextChanged="SearchTextBox_TextChanged" > 
<i:Interaction.Triggers> 
    <i:EventTrigger EventName="TextChanged"> 
     <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding TextChanged, Mode=OneWay}" CommandParameter="{Binding Text, ElementName=SearchTextBox}"/> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

由於某些原因,messagebox顯示一個字符延遲一個字符。

+0

歡迎來到stackoverflow!請注意,您不應在此回覆答案,要麼使用評論或編輯原始帖子,答案沒有任何順序。 – 2010-05-03 09:40:02

1

這適用於通過RelayCommand參數的TextBox。督察 - RelayCommand<TextBox>

<TextBox Height="72" HorizontalAlignment="Left" Margin="8,136,0,0" Name="txtFilter" Text="" VerticalAlignment="Top" Width="460" > 
     <interactivity:Interaction.Triggers> 
      <interactivity:EventTrigger EventName="TextChanged"> 
       <cmd:EventToCommand Command="{Binding SearchedTextChanged}" CommandParameter="{Binding ElementName=txtFilter}" /> 
      </interactivity:EventTrigger> 
     </interactivity:Interaction.Triggers> 
    </TextBox> 

public RelayCommand<TextBox> SearchedTextChanged { get; set; } 

SearchedTextChanged = new RelayCommand<TextBox>(OnSearchedTextChanged); 

private void OnSearchedTextChanged(TextBox val) 
    { 
     if (val != null) 
     { 
      System.Diagnostics.Debug.WriteLine(val.Text); 
     } 
    } 
1

我也有類似的問題,並發現數據綁定操作不總是觸發,直到文本框失去焦點。但是,命令將立即開始。

如果要在使用該值之前確保數據綁定已發生,可以在控件上調用BindingExpression.UpdateSource()方法。嘗試是這樣的:

var bindTarget = SearchTextBox.GetBindingExpression(TextBox.TextProperty); 
bindTarget.UpdateSource(); 

爲了避免直接在您的視圖模型指的是你的文本框(因爲你應該MVVM),你可以使用FocusManager.GetFocusedElement()。這在處理ApplicationBar按鈕時特別有用,因爲它們在使用時似乎沒有獲得焦點。