wpf TextBox TextChanged 事件问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17280277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:03:57  来源:igfitidea点击:

TextBox TextChanged Event Problems

c#wpfmvvmtextbox

提问by TSM

I'm using a basic TextBox that is bound to an object. Basically, what I want to do is call a method every time the text in the box is edited and the user de-selects the box or when the underlying bound data is edited. What I am using right now is the TextChanged event, but this has a few problems:

我正在使用绑定到对象的基本 TextBox。基本上,我想要做的是每次编辑框中的文本并且用户取消选择框或编辑底层绑定数据时调用一个方法。我现在使用的是 TextChanged 事件,但这有一些问题:

  1. It is called when the TextBox is first created, and I don't want this.

  2. It is called every time a new character is added, and I only want it called when the underlying bound data is changed (which seems to be whenever focus shifts from the box).

  1. 它在首次创建 TextBox 时被调用,我不想要这个。

  2. 每次添加新字符时都会调用它,我只希望在底层绑定数据发生更改时调用它(这似乎是每当焦点从框移开时)。

How can I accomplish this?

我怎样才能做到这一点?

EDIT: I've tried several other TextBox properties like Get/LostFocus but they never seem to fire.

编辑:我尝试过其他几个 TextBox 属性,例如 Get/LostFocus,但它们似乎从未触发过。

Also, I don't want to put this method call in the Setter of the Property, because the underlying data is something that is logically separate from the UI of this project and I don't want any method calls that relate to doing computations for the UI.

此外,我不想将此方法调用放在属性的 Setter 中,因为底层数据在逻辑上与此项目的 UI 分开,并且我不希望任何与执行计算相关的方法调用用户界面。

回答by user2517337

The event LostFocusfires when the focus is shifted from the current element. I tried it and its working fine.

LostFocus当焦点从当前元素转移时触发该事件。我试过了,效果很好。

回答by Bill Zhang

As jods says, the best way to bind your TextBox's Text to ViewModel's property. The Code are:

正如 jods 所说,将 TextBox 的 Text 绑定到 ViewModel 属性的最佳方法。代码是:

View:

看法:

<TextBox x:Name="TextBox1" Text="{Binding Path=Text1,Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>

ViewModel:

视图模型:

    public string Text1
    {
        get { return _text1; }
        set
        {
            _text1 = value;
            RaisePropertyChanged("Text1");
        }
    }

View code behind:

查看后面的代码:

    private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Text1")
        {
            //Call UI related method...
        }
    }

In this way, it satisfy your two conditions: 1. Every time when you edit TextBox and lose the focus, Setter of Text1 will be called and ViewModel will raise PropertyChanged event. 2. When underlying Text1 is changed. Text1 will also raise the event so View can know it.

这样就满足了你的两个条件: 1. 每次编辑TextBox 失去焦点时,Text1 的Setter 会被调用,ViewModel 会引发PropertyChanged 事件。2. 当底层 Text1 发生变化时。Text1 也会引发事件,以便 View 可以知道它。

Also it can avoid your two concerns: 1. In the first time binding, only getter of Text1 is called. No event is raised. 2. Setter of Text1 is only called after TextBox is lost focus.

它也可以避免您的两个顾虑: 1. 在第一次绑定时,只调用 Text1 的 getter。不引发任何事件。2、Text1的Setter只有在TextBox失去焦点后才会被调用。

回答by jods

Best design is to listen for changes in the underlying bound property. You can do that without changing the setter if you use a DependencyProperty or if your object implements INotifyPropertyChanged.

最好的设计是监听底层绑定属性的变化。如果您使用 DependencyProperty 或您的对象实现 INotifyPropertyChanged,则无需更改 setter 即可完成此操作。

When the underlying property changes (LostFocus by default, or each char at a time) is a binding option.

当基础属性更改时(默认情况下为 LostFocus,或一次更改每个字符)是一个绑定选项。

If you don't want to follow my advice of listenning for changes in your (view-)model, you could subscribe to GotFocus and LostFocus events. Save the current value when you get focus, compare with current value when you lose it. If it's different -> do what it is you want to do.

如果您不想听从我的建议(视图-)模型中的更改,您可以订阅 GotFocus 和 LostFocus 事件。获得焦点时保存当前值,失去焦点时与当前值进行比较。如果不同 -> 做你想做的事。

回答by Wojciech Kulik

every time the text in the box is edited and the user de-selects the box

每次编辑框中的文本并且用户取消选择框时

Hmmm AFAIK it's a standard behaviour of TextBox if you bind text like that: Text={Binding Property}

嗯 AFAIK 如果你像这样绑定文本,它是 TextBox 的标准行为: Text={Binding Property}

when the underlying bound data is edited

当底层绑定数据被编辑时

You can provide this functionality inside setter of your property.

您可以在您的财产的 setter 中提供此功能。

回答by Ganesh

I am not sure what you are finally trying to achieve but I am going to take a guess at this. If you are following an MVVM pattern then, then it seems like you can achieve what you want by using the updateSourceTrigger property of the binding. If you are not using MVVM then you might what to take a look at using MVVM

我不确定您最终要实现什么目标,但我将对此进行猜测。如果您正在遵循 MVVM 模式,那么您似乎可以通过使用绑定的 updateSourceTrigger 属性来实现您想要的。如果您不使用 MVVM,那么您可能需要看看使用 MVVM