如何在 TextChanged 事件中通过 CommandParameter 传递更新的文本?

How to pass the updated text by CommandParameter in TextChagned event?

这是一个有趣的案例。我使用 MVVMLight 捕获文本框的事件 TextChagned 并将其传递给 ViewModel 中的命令,不知何故 CommandParameter 传递的文本值仍然是更新前的旧文本。 有人知道如何获取新文本吗?

<Grid>
    <TextBox x:Name="myTextBox" HorizontalAlignment="Left" 
             Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="Hello" 
             VerticalAlignment="Top" Width="120">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="TextChanged">
                <cmd:EventToCommand Command="{Binding Mode=OneWay,Path=TextChangedCommand}" 
                                    PassEventArgsToCommand="True"
                                    CommandParameter="{Binding Path=Text,ElementName=myTextBox}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>
    <Button Content="Button" HorizontalAlignment="Left" Margin="352,214,0,0" 
            VerticalAlignment="Top" Width="75" Click="Button_Click"/>




</Grid>

public class MainViewModel : ViewModelBase
{
    /// <summary>
    /// Initializes a new instance of the MainViewModel class.
    /// </summary>
    public MainViewModel()
    {
        ////if (IsInDesignMode)
        ////{
        ////    // Code runs in Blend --> create design time data.
        ////}
        ////else
        ////{
        ////    // Code runs "for real"
        ////}
    }

    private RelayCommand<string> _textChangedCommand;

    public RelayCommand<string> TextChangedCommand
    {
        get 
        {
            if (this._textChangedCommand == null)
            {
                this._textChangedCommand = new RelayCommand<string>(this.TextChanged);
            }
            return this._textChangedCommand; 
        }
    }

    private void TextChanged(string input)
    {
        MessageBox.Show(input);
    }

}

我正在深入研究 MVVM Light 的代码,在 EventToCommand.cs 的 Invoke 方法中,参数似乎仍然具有其旧值。我没有进一步查看,但也许这是 MVVM 中的错误。

不过,您可以采取一种解决方法。

创建一个新的 class 实现 IEventArgsConverter,类似于:

public class TextChangedEventArgsConverter : IEventArgsConverter
{
    public object Convert(object value, object parameter)
    {
        var textChangedEventArgs = (TextChangedEventArgs) value;
        return ((TextBox) textChangedEventArgs.Source).Text;
    }
}

将它添加到 WindowResourceDictionaryResources 集合中,其中 EventToCommand 无法正常工作。

<Window.Resources>
    <textChanged:TextChangedEventArgsConverter x:Key="TextChangedEventArgsConverter" />
</Window.Resources>

并将 EventToCommand 更改为以下内容:

<cmd:EventToCommand Command="{Binding Mode=OneWay,Path=TextChangedCommand}" 
                    PassEventArgsToCommand="True"
                    EventArgsConverter="{StaticResource TextChangedEventArgsConverter}" />

因此指定的 EventArgsConverter 将接收实际的 TextChangedEventArgs 并将提取 Text 本身,这将是正确的值。

通过这些更改,我能够实现您正在寻找的东西。

顺便说一句:不要同时使用 CommandParameterPassEventArgsToCommand="True"。正如 documentation 所说,如果您将 PassEventArgsToCommand 设置为 true,则 RelayCommand 的类型参数应该是事件的事件参数类型,在这种情况下为 TextChangedEventArgs .