我有一个动态WPF输入表单,根据数据集合的内容显示输入文本框列表。每个文本框的文本都绑定到数据中的值字段,当这些字段中的任何一个更改时,我正在使用触发命令,然后使用输入字段的值在脚本中执行计算(也是动态提供的)。 / p>
我的问题是如何在字段值更改后让Command执行。目前,我正在使用TextChanged属性基于事件触发器触发Command。
问题是TextChanged属性似乎在设置bound属性的值之前触发。这意味着虽然命令触发并执行脚本,但当前正在编辑的字段将具有“旧”字样。其中的数据仍然是由于事件的顺序。
我正在使用的XAML代码的相关位是:
<Label Visibility="{Binding HasInputFieldsSection, Converter={StaticResource visibilityConverter}}">Input parameters</Label>
<ItemsControl Visibility="{Binding HasInputFieldsSection, Converter={StaticResource visibilityConverter}}"
ItemsSource="{Binding Path=SelectedQualificationType.QualificationTypeInputFields.QualificationTypeFields}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Label Content="{Binding Label}" Visibility="{Binding Label, Converter={StaticResource stringVisibilityConverter}}"/>
<TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged, Delay=250}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<cmd:EventToCommand Command="{Binding DataContext.ExecuteExpressionsCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我希望有一个不同的事件我可以触发命令但是在查看WPF文本框的文档并尝试了一些替代方案之后,它们似乎都不合适。
我可以将绑定更改为基于LostFocus而不是PropertyChanged,但为了获得更好的用户体验,我宁愿不这样做。同样,我可以删除输入TextBox绑定的延迟,但理想情况下我希望保留此延迟,再次为用户体验。
简而言之,目前的顺序似乎是:
但我需要它更像:
是否有更好的事件可以解雇或完成我想要做的事情?
答案 0 :(得分:2)
您可以使用Binding.SourceUpdated Attached Event代替TextChanged
事件。
将Binding
上的Binding.NotifyOnSourceUpdated属性设置为true
并收听附加的事件:
<TextBox Text="{Binding Value, NotifyOnSourceUpdated=True}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SourceUpdated">
<!--...-->
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
使用这种方法,您的命令将在Binding
数据传输回模型层后立即触发。
答案 1 :(得分:1)
我的问题是如何在字段值更改后让Command执行。目前,我正在使用TextChanged属性基于事件触发器触发Command。
在设置Value
集合中任何项目的QualificationTypeFields
属性时,在视图模型中触发命令。
您只需简单地为集合中的每个项目挂接PropertyChanged
事件的事件处理程序,如下所示:
foreach(var item in SelectedQualificationType.QualificationTypeInputFields.QualificationTypeFields)
{
item.PropertyChanged += item_PropertyChanged;
}
...
private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Value")
{
ExecuteExpressionsCommand.Execute(null);
}
}
如果QualificationTypeFields
是ObservableCollection<T>
,您还应该记住将事件处理程序添加到您添加到集合中的每个新项目。您可以通过处理CollectionChanged
事件轻松完成此操作:
private void QualificationTypeFields_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (object item in e.NewItems)
{
(item as INotifyPropertyChanged).PropertyChanged
+= new PropertyChangedEventHandler(item_PropertyChanged);
}
}
if (e.OldItems != null)
{
foreach (object item in e.OldItems)
{
(item as INotifyPropertyChanged).PropertyChanged
-= new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}