说我有一个WPF TextBox
:
<TextBox Text="{Binding Foo}" />
ICommand
更新属性Foo
之后是否有办法执行某些TextBox
(即由TextBox
而非某些其他控件或代码)?
我不想使用绑定的SourceUpdated事件,因为我想避免“代码隐藏”。
答案 0 :(得分:3)
你确实意识到MVVM警察如果最终得到一些代码而不会来找你?使用事件命令等基本上只是在XAML而不是在C#中进行编码。无论哪种方式,您都需要将事件挂钩到命令,因为控件不会公开您所追求的命令。
我认为这就是你所追求的,如果我走错了路,请告诉我:
您想知道Foo的更新何时来自文本框和文本框。即如果对Foo的更新来自某些您不希望命令运行的代码,请更正吗?
如果是这样的话:
<TextBox Name="Fred" Text="{Binding Foo, NotifyOnSourceUpdated=True}" SourceUpdated="Fred_SourceUpdated"/>
然后在&#34;邪恶&#34;代码背后有:
private void Fred_SourceUpdated(object sender, DataTransferEventArgs e)
{
}
在该方法中,您可以将视图的datacontext转换为viewmodel并调用您想要的任何命令。如果其他内容更新了Foo,则不会调用源更新事件。
如果你真的想在你的OP中提到没有代码,那么你可以做一个附加的行为,但这对于一个&#34;废话&#34;需求。您的逻辑取决于更改是否来自文本框这一事实意味着您的视图已不仅仅是一个视图。此方法仍允许您在VM中完全测试命令代码。
第二次修改
您还可以通过事件命令而不是文本更改来查看在XAML中使用源更新事件
答案 1 :(得分:1)
您可以尝试创建一个方法来执行您想要完成的任何操作,并在调用raisepropertychanged()之后调用该方法。例如
public void MyMethod()
{
//Do whatever;
}
然后在你的属性getter setter:
public string MyText
{
get { return _MyText; }
set
{
_MyText = value;
RaisePropertyChanged("MyText")
// THen call that method
MyMehtod();
}
}
语法可能已关闭,我最近习惯做vb。希望这会有所帮助,但如果您需要其他选择,还有其他方法。
编辑2:
<Textbox Text="{Binding Foo}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding TextChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
TextChangedCommand位于您的viewmodel
中不确定TextChanged是否为EventName,我不记得所有可用的事件类型
答案 2 :(得分:0)
假设您已实施INotifyPropertyChanged
,则只需处理PropertyChanged
事件即可。您在事件处理程序中执行该命令。此事件处理程序位于ViewModel中(不是您的代码)。
修改强>
以下是MVVM Light中EventToCommand行为的工作原理示例。您可以使用此允许使用命令处理任何事件。
<Rectangle Fill="White"
Stroke="Black"
Width="200"
Height="100">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<cmd:EventToCommand Command="{Binding TestCommand,
Mode=OneWay}"
CommandParameter="{Binding Text,
ElementName=MyTextBox,
Mode=OneWay}"
MustToggleIsEnabledValue="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
修改2
另一个想法是在通过代码更改Foo
时始终使用方法。这样,您就知道用户必须更改任何不使用该方法的Foo
更改。
private bool _isFooUpdating;
private void SetFoo(string value)
{
_isFooUpdating = true;
Foo = value;
_isFooUpdating = false;
}
public string Foo
{
get { return _foo; }
set
{
if (_foo = value) return;
_foo = value;
OnFooChanged();
OnPropertyChanged("Foo");
}
}
private void OnFooChanged()
{
if (_isFooUpdating) return;
FooChangedCommand.Execute();
}