更新边界值以使其变化 [英] Updating a bounded value as its changing

查看:90
本文介绍了更新边界值以使其变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我相信我在WinForms中也遇到了文本更改事件,但是我可能会误会这一问题.无论如何,我都想知道如何(或是否可以)在WPF中解决.注意我正在使用MVVM模式.

假设我在视图中有一个TextBox绑定到其视图模型中的值"Value".

随着最终用户键入或更改,文本代码不会被触发.只有当鼠标转到另一个组件(例如,文本框或列表框.实际上是任何东西)时,该值才会在viewModel中更新.
这当然会造成问题.假设当用户按下"Ctrl + S"时,此值"将保存到某些文件中.该值尚未获取文本框中的内容,因此它是旧值.然后,用户认为他们保存了新数据,但除了保存旧数据外,什么也没有做.

那么,在保存之前如何不告知最终用户[点击这里]的情况下如何处理呢?

编辑(附加代码示例)
主视图在App.xaml.cs
中是这样绑定的

I belive I saw this problem in WinForms also with the text changed event but I maybe mistaken. Regardless I want to know how (or if it can be) solved in WPF. Note I am using an MVVM pattern.

Say I have a TextBox in the view bound to a value ''Value'' in its view model.

As the end user types or changes the text code is not fired. It is only when the mouse goes to another component (e.g. textbox or listbox.. really anyting) that the value is updated in the viewModel.
This can of course create problems. Say this ''Value'' is saved to some file when the user presses ''Ctrl+S''. The value has not yet grabbed what is in the textbox so it is the old value. The user then thinks they saved new data but really did nothing but save old over old.

So How does one handle this without telling his end users [CLICK HERE] before saving?

EDIT (Addid code samples)
The main view is bound as such in the App.xaml.cs

<pre lang="cs">private void OnStartup(object sender, StartupEventArgs e)
        {
            // Create the ViewModel and expose it using the View''s DataContext
            MainWindow view = new MainWindow();
            view.DataContext = new MainViewModel();
            view.Show();
        }





所有其他内容都绑定在由主视图提取的资源中.它们的绑定就是这样,





All others are bound in a resource that is pulled in by the main view. Their binding is as such,

<DataTemplate DataType="{x:Type viewModels:Example_vm}">
    <views:Example_v/>
</DataTemplate>




具有文本框的对象如下:




The object that has the Textbox is as follows:

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Text="{Binding Path=Name}"/>
        <TextBox Grid.Column="1" Text="{Binding Path=Value, Mode=TwoWay}"/>
    </Grid>




其有界代码为:




And its bounded code is:

#region Value
        public string Value
        {
            get { return _settingNode.Attribute(Setting_Properties.Value).Value; }
            set
            {
                if (_settingNode.Attribute(Setting_Properties.Value).Value == value)
                    return;
                _settingNode.Attribute(Setting_Properties.Value).SetValue(value);

                this.RaisePropertyChanged("Value");
                this.RaisePropertyChanged("Node");
            }
        }
        #endregion //Value

        <pre lang="cs">#region Name
public string Name
{
    get { return _settingNode.Attribute(Setting_Properties.Name).Value; }
    set
    {
        if (_settingNode.Attribute(Setting_Properties.Name).Value == value)
            return;
        _settingNode.Attribute(Setting_Properties.Name).SetValue(value);

        this.RaisePropertyChanged("Name");
        this.RaisePropertyChanged("Node");
    }
}
#endregion //Name



_settingNode是一个XElement,其中包含所需的数据.



_settingNode is an XElement that contains the data needed.

推荐答案

由于这是WPF,因此解决方案非常简单:

Since this is WPF, the solution is fairly simple:

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Text="{Binding Path=Name}"/>
        <TextBox Grid.Column="1" Text="{Binding Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    </Grid>



问题是您将BindingExpression的UpdateSourceTrigger属性保留为其默认值LostFocus,而不是使用PropertyChanged.

如果您愿意在Silverlight中实现相同的功能,请查看我关于它的文章在Silverlight上更新PropertyChanged上的源 [ ^ ]

有关BindingExpressions的详细信息,我建议 WPF Binding CheatSheet 1.1版 [



The issue is that you are leaving the UpdateSourceTrigger Property of the BindingExpression to its default value, which is LostFocus, instead of using the PropertyChanged.

If you are willing to achieve this same functionality in Silverlight, check my article about it Updating Source on PropertyChanged on Silverlight[^]

For more info about BindingExpressions I recommend the WPF Binding CheatSheet version 1.1[^]

Hope this helps you.
Best regards.
Raul Mainardi Neto


这根本不是问题.这是设计使然.所需事件在值已更新时触发,而不是在值更新时触发.按键类型事件是您在用户键入数据时用来跟踪数据的事件.
This is not a problem at all. It''s by design. The event you want, fires when the value has been updated, not while it is updating. Keypress type events are what you use to track your data WHILE the user is typing.


我猜您在MVVM中使用了一些与TextBox的数据绑定.我对吗?如果是这样.尝试在Binding表达式中使用Mode = TwoWay.如果不是,则与WPF无关,但发现有两个事件可以正确触发:KeyDown(可以对您按下的任何键进行有点混乱的触发,以及TextChanged事件.正如克里斯蒂安所说,您可以在此事件中更新源代码.
I guess in MVVM youre using some databinding to TextBox. Am I right? If so. Try use Mode=TwoWay in Binding expression. If not, haven''t to many to do with WPF but found two events firing properly: KeyDown(can be bit messy firing on any key you pressed, and TextChanged event. As Christian said, you can update your source in this event.


这篇关于更新边界值以使其变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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