忽略由于数据绑定而导致的文本/值更改

时间:2011-10-20 19:38:58

标签: wpf data-binding

当数据绑定发生时,如何忽略对控件的更改?我尝试挂钩各种事件,如gotfocus,textchanged和leavefocus,但如果控件已经有焦点并且用户“取消”他们的更改,当我重新加载记录和数据绑定接管时,textchanged认为用户仍然进行了更改,因为重点是控制。调用堆栈为空。是否有任何全局数据绑定事件,如数据绑定启动和数据绑定结束?我看到我在哪里解雇我的OnProperyChanged但在该调用中,数据绑定不会发生。看起来它正在“排队”并在其他地方运行。

有一次,我将在我们的视图模型中挂钩属性更改事件,但这意味着我将无法检测到并且无法显示窗体被修改,直到用户离开控件。我知道,我知道,我可以更改所有绑定,以便在每次更改字符时立即进行绑定,但由于用户尚未完成输入值,因此会出现一些验证情况。

我真的很喜欢像TextChangedByUser这样的事件,它会触发用户是否使用了密钥,剪贴板,鼠标剪贴板,以及用户触发的任何内容。

我无法弄清楚如何区分用户更改和数据绑定更改。

3 个答案:

答案 0 :(得分:6)

  

我真的很喜欢像TextChangedByUser那样的事件   触发用户是否使用了密钥,剪贴板,鼠标剪贴板等   由用户触发。

     

我只是无法弄清楚如何区分用户的变化和   数据绑定变化。

请勿使用Text.TextChanged事件来检测用户输入,
改为使用Binding.SourceUpdated事件。

或者更一般: 不要使用可视元素的DP来检测用户更新,而是使用Binding.SourceUpdated事件。

这是一个RoutedEvent。 在绑定时,您必须设置NotifyOnSourceUpdated = true。在UpdateSourceTrigger的帮助下,当您想要获得通知时,您甚至可以进行微调。

<小时/> 你的xaml可能是这样的:

<Grid x:Name="LayoutRoot" Binding.SourceUpdated="LayoutRoot_SourceUpdated">
    ...
    <TextBox>
        <TextBox.Text>
            <Binding NotifyOnSourceUpdated="True" Path="path" UpdateSourceTrigger="PropertyChanged" >
            </Binding>
        </TextBox.Text>
</Grid>

您的活动可能是这样的:

private void LayoutRoot_SourceUpdated(object sender, DataTransferEventArgs e)
{
    // called every time s.th. changed by user
}

(由于评论而编辑)
为什么这是检测用户是否以任何方式触发输入的有效方法? 在给定的示例中,TextBox的DataContext'path'属性是 source ,而'TextBox.Text'属性是 target
[数据绑定概述] http://msdn.microsoft.com/en-us/library/ms752347.aspx
TextBox.Text属性在绑定初始化时第一次更改,并且source-value被写入'TextBox.Text'属性。因为您不知道绑定何时发生,所以不能使用TextBox.Text属性或其任何事件(例如TextChanged)来检测用户输入。因此: 不要使用Text.TextChanged事件来检测用户输入!更一般:不要使用视觉元素的DP来检测用户更新!!!

如果用户更改了可视文本字段的内容,则“TextBox.Text”属性会更改(您的目标)。之后,绑定会更新UpdateSourceTrigger定义的时间。这是SourceUpdated事件被触发的时间。

我承认不知道绑定外部对绑定源的更改的影响。 但是我有一个完整的类似编辑器的桌面应用程序,用户通过这种方式检测更改,并且工作得非常好。

答案 1 :(得分:0)

您应该更新您的绑定代码以设置以下

{Binding Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}

编辑:对不起,我已经监督了你已经知道的事实......在这种情况下,我无法帮助:(

答案 2 :(得分:0)

您可以使用UIElement.TextInput event检测用户输入。

请注意,事件可能已由输入控件本身处理,因此您可能必须使用UIElement.PreviewTextInput event