如何在 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;
}
}
将它添加到 Window
或 ResourceDictionary
的 Resources
集合中,其中 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
本身,这将是正确的值。
通过这些更改,我能够实现您正在寻找的东西。
顺便说一句:不要同时使用 CommandParameter
和 PassEventArgsToCommand="True"
。正如 documentation 所说,如果您将 PassEventArgsToCommand
设置为 true,则 RelayCommand
的类型参数应该是事件的事件参数类型,在这种情况下为 TextChangedEventArgs
.
这是一个有趣的案例。我使用 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;
}
}
将它添加到 Window
或 ResourceDictionary
的 Resources
集合中,其中 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
本身,这将是正确的值。
通过这些更改,我能够实现您正在寻找的东西。
顺便说一句:不要同时使用 CommandParameter
和 PassEventArgsToCommand="True"
。正如 documentation 所说,如果您将 PassEventArgsToCommand
设置为 true,则 RelayCommand
的类型参数应该是事件的事件参数类型,在这种情况下为 TextChangedEventArgs
.