当bound属性执行某些业务规则时,绑定的WPF TextBox不会更新值 [英] Bound WPF TextBox is not updating value when the bound property enforces some business rules

查看:113
本文介绍了当bound属性执行某些业务规则时,绑定的WPF TextBox不会更新值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用.NET 4.0。我有一些非常简单的代码,可让用户输入1到99,999(含)之间的数字。我在属性设置器中有一些逻辑,可以防止在不遵循业务规则的情况下应用最新值(例如,它不是数字或数字太大)。

 公共类MainViewModel:INotifyPropertyChanged 
{
#region字段

私有字符串_text = string.Empty;

#endregion //字段

#region属性

公共字符串Text
{
get {return _text; }

set
{
if(_text == value)return;

if(IsValidRange(value))
{
_text = value;
}

OnPropertyChanged( Text);
}
}

#endregion //属性

#region私有方法

private bool IsValidRange(string value)
{
//一个空字符串被认为是有效的。
if(string.IsNullOrWhiteSpace(value))返回true;

//我们尝试转换为无符号整数,因为不允许使用负的账单号,因此
//也不是小数位。
uint num;
if(!uint.TryParse(value,out num))返回false;

//该值已成功解析,因此我们知道它是一个非负整数。现在,我们
//只需要确保它在1-99999(含)范围内即可。
return num> = 1&& num< = 99999;
}

#endregion //私有方法

#region INotifyPropertyChanged实现

公共事件PropertyChangedEventHandler PropertyChanged;

[NotifyPropertyChangedInvocator]
受保护的虚拟void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if(handler!= null)handler(this,new PropertyChangedEventArgs(propertyName));
}

#endregion // INotifyPropertyChanged实现
}

我遇到的问题是,当该值无效并且我只是忽略该值时,绑定到此属性的TextBox不会更新以反映该更改。相反,它只是保留键入时的值。这是我绑定属性的方式:

 < TextBox Grid .Row = 0 
Text = {Binding Path = Text,UpdateSourceTrigger = PropertyChanged,Mode = TwoWay} />

有人可以告诉我我在做什么错吗?



我读了很多看起来与此非常相似的问题,但是没有一个答案对我有用。奇怪的是,当我不根据数字进行验证时,只要将输入的所有文本都更改为大写,就可以了。当我尝试不将Property设置为新值时,它似乎不起作用。

解决方案

这似乎是一个错误使用.NET 3.5-4.0中的 TextBox 。我首先在4.5中进行了尝试,您的代码按编写的方式工作,但是当我将项目转换为4.0时,我可以重现该问题。经过一番搜索后,我发现:



,WPF文本框拒绝更新自身,其中详细介绍了引用以下方法: p>

文本框与viewmodel属性不同步



当然,如果您可以使用.NET 4.5,我建议这样做,但当然并不总是那么简单。


I am using .NET 4.0. I have some very simple code that lets the user type in a number between 1 and 99,999 (inclusive). I have some logic in the Property setter that prevents the latest value from being applied if it does not adhere to the business rules (e.g., it is not a number or the number is too large).

    public class MainViewModel : INotifyPropertyChanged
{
    #region Fields

    private string _text = string.Empty;

    #endregion // Fields

    #region Properties

    public string Text
    {
        get { return _text; }

        set
        {
            if (_text == value) return;

            if (IsValidRange(value))
            {
                _text = value;
            }

            OnPropertyChanged("Text");
        }
    }

    #endregion // Properties

    #region Private Methods

    private bool IsValidRange(string value)
    {
        // An empty string is considered valid.
        if (string.IsNullOrWhiteSpace(value)) return true;

        // We try to convert to an unsigned integer, since negative bill numbers are not allowed,
        // nor are decimal places.
        uint num;
        if (!uint.TryParse(value, out num)) return false;

        // The value was successfully parse, so we know it is a non-negative integer.  Now, we
        // just need to make sure it is in the range of 1 - 99999, inclusive.
        return num >= 1 && num <= 99999;
    }

    #endregion // Private Methods

    #region INotifyPropertyChanged Implementation

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion // INotifyPropertyChanged Implementation
}

The problem I am running into is that when the value is not valid and I just ignore the value, the TextBox bound to this property does not update to reflect that change; rather, it just retains the value as it is typed in. Here is how I have the property bound:

        <TextBox Grid.Row="0"
             Text="{Binding Path=Text, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>

Can anyone tell me what I'm doing wrong?

I have read a lot of questions that seemed very similar to this, but none of the answers worked for me. The weird thing is that when I don't validate based on numbers, but just change all text typed in to be upper case, it works just fine. It just seems to not work when I try to not set the Property to the new value.

解决方案

This seems to be a bug with the TextBox in .NET 3.5-4.0. I first tried this in 4.5 and your code worked as written, but when I converted the project to 4.0, I could reproduce the issue. After doing some searching, I found:

WPF Textbox refuses to update itself while binded to a view model property, which details a workaround that references:

Textbox getting out of sync with viewmodel property.

Of course if it's possible for you to use .NET 4.5 I'd suggest that, but of course it's not always as easy as that.

这篇关于当bound属性执行某些业务规则时,绑定的WPF TextBox不会更新值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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