MVVM Light太快了:)

Hik*_*ari 4 silverlight command mvvm windows-phone-7 mvvm-light

我有一个简单的WM7页面TextBox.更进一步,我指定EventToCommand(a RelayCommand<string>)对此事件TextBox作出反应TextChanged.为了测试pourposes我TextBox_TextChanged在页面的代码后面做了另外的方法.命令和TextBox_TextChanged打印带有文本框内容的消息框.

初始值TextBox"ABC".然后我按下D和:

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

为什么命令这么快?

命令声明:

public RelayCommand<string> TextChanged {get; private set;}
Run Code Online (Sandbox Code Playgroud)

命令初始化:

TextChanged = new RelayCommand<string>((s) => MessageBox.Show(s));
Run Code Online (Sandbox Code Playgroud)

命令绑定:

<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>
Run Code Online (Sandbox Code Playgroud)

Igo*_*aka 6

我无法重现这种行为.我尝试过使用EventToCommand和一个Behavior(它只是监听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>
Run Code Online (Sandbox Code Playgroud)

在viewmodel中

m_TestTextChangedCommand = new RelayCommand<string>(val => System.Diagnostics.Debug.WriteLine(val));
Run Code Online (Sandbox Code Playgroud)

如您所见,我使用命令参数将文本框的值传递给viewmodel.这样,viewmodel不必知道文本框以获取文本值.

此方法的替代方法是使用行为和TwoWay绑定来更新属性:

<TextBox Name="SearchTextBox" Text="{Binding TextInViewModel, Mode=TwoWay}" >
  <i:Interaction.Behaviors>
    <sc:UpdateOnTextChangedBehavior/>
  </i:Interaction.Behaviors>
</TextBox>
Run Code Online (Sandbox Code Playgroud)

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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

什么上面所做的是模拟天生的桌面WPF的行为BindingUpdateSourceTrigger=PropertyChanged,这是在Silverlight中失踪.那么只要你输入文本框TextInViewModel属性就会发生什么会更新.这个属性不是一个DependencyProperty,它可能只是一个普通的CLR属性.