【问题标题】:How to pass the updated text by CommandParameter in TextChagned event?如何在 TextChagned 事件中通过 CommandParameter 传递更新的文本?
【发布时间】:2015-09-13 17:27:27
【问题描述】:

这是一个有趣的案例。我使用 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);
    }

}

【问题讨论】:

  • 能贴出C#代码吗?

标签: c# wpf mvvm binding mvvm-light


【解决方案1】:

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

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

创建一个实现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

【讨论】:

  • 谢谢!当我在等待帮助时,我做了同样的事情。相反,我将 TextBox 放在 CommandParameter 中,并且代码读取了 TextBox=>Text 属性并且它起作用了。奇怪!
  • 谢谢。这指示我使用转换器来解决列表框的鼠标双击问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
相关资源
最近更新 更多