WPF TextBox EventTrigger事件序列 [英] WPF TextBox EventTrigger sequence of events

查看:91
本文介绍了WPF TextBox EventTrigger事件序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个动态的WPF输入表单,其中根据数据集合的内容显示输入文本框的列表.每个文本框的文本都绑定到数据中的值"字段,当这些字段中的任何一个发生更改时,我都会触发命令,然后使用输入字段的值在脚本(也动态提供)中执行计算./p>

我的问题是在字段值更改后如何使命令执行.目前,我使用TextChanged属性基于事件触发器触发Command.

问题在于,在设置bound属性的值之前,TextChanged属性似乎已启动.这意味着尽管命令会触发并执行脚本,但是由于事件的顺序,当前正在编辑的字段中仍将包含旧"数据.

我正在使用的XAML代码的相关位是:

 <标签可见性="{Binding HasInputFieldsSection,Converter = {StaticResourcevisibleconverter}}">输入参数</Label>< ItemsControl Visibility ="{Binding HasInputFieldsSection,Converter = {StaticResource visibleConverter}}"ItemsSource ="{Binding Path = SelectedQualificationType.QualificationTypeInputFields.QualificationTypeFields}">< ItemsControl.ItemTemplate>< DataTemplate>< StackPanel><标签内容="{绑定标签}"可见性="{绑定标签,转换器= {StaticResource stringVisibilityConverter}}"/>< TextBox Text ="{绑定值,UpdateSourceTrigger =属性更改,延迟= 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绑定上的延迟,但是理想情况下,我还是希望这种延迟得以保留,再次为用户带来体验.

所以简而言之,当前顺序似乎是:

  1. 用户键入某些内容
  2. 更改的文字被解雇
  3. 命令被触发
  4. 绑定字段已更新

但我需要使其更像:

  1. 用户键入某些内容
  2. 更改的文字被解雇
  3. 绑定字段已更新
  4. 命令被触发

是否有更好的办法可以解雇或完成我想做的事情?

解决方案

您可以使用

采用这种方法,您将在 Binding 数据传输回模型层后立即触发您的命令.

I have a dynamic WPF input form, whereby a list of input text boxes is displayed based on the contents of a collection of data. The text of each text box is bound to a Value field in the data, when any of these fields changes I am using firing a Command which then executes a calculation in a script (also dynamically provided) using the values of the input field.

My question is how I can get the Command to execute after the field value has changed. At the moment I am firing the Command based on an event trigger using the TextChanged property.

The issue is that the TextChanged property seems to fire before the value of the bound property is set. This means that although the command fires and executes the script, the field which is currently being editing will have the 'old' data in it still because of the sequence of events.

The relevant bit of XAML code I am using is:

<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>

I was hoping there would be a different event I could trigger the command on but after looking through the documentation for a WPF textbox and trying some alternative none of them seem appropriate.

I could change the binding to be based on LostFocus rather than PropertyChanged but for a better user experience I would rather not. Likewise I could remove the delay on the input TextBox binding but ideally I would want this delay to remain, again for user experience.

So in short the current sequence seems to be:

  1. user types something
  2. text changed gets fired
  3. command is fired
  4. bound field gets updated

but I need it to be more like:

  1. user types something
  2. text changed gets fired
  3. bound field gets updated
  4. command is fired

Is there a better event to fire off or way to accomplish what I am trying to do?

解决方案

You can use the Binding.SourceUpdated Attached Event instead of the TextChanged event.

Set the Binding.NotifyOnSourceUpdated property on your Binding to true and listen to the attached event:

<TextBox Text="{Binding Value, NotifyOnSourceUpdated=True}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SourceUpdated">
            <!--...-->
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

With this approach, your command will be triggered just after the Binding data transfer back to the model layer.

这篇关于WPF TextBox EventTrigger事件序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆