强制WPF TextBox在.NET 4.0中不再工作 [英] Coerce a WPF TextBox not working anymore in .NET 4.0

查看:182
本文介绍了强制WPF TextBox在.NET 4.0中不再工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的WPF应用程序中,我有一个TextBox,用户可以输入一个百分比(int,介于1和100之间)。 Text属性是数据绑定到一个ViewModel中的属性,我强制该值在setter的给定范围内。



然而,在.NET 3.5中,在强制执行后,UI中的数据未正确显示。在 MSDN上的这篇文章,WPF博士说,您必须手动更新绑定,以便正确显示。因此,我有一个 TextChanged 处理程序(在View中)调用 UpdateTarget()。在代码中:



查看XAML:

 < TextBox Text = {Binding Percentage,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged,TargetNullValue = {x:Static sys:String.Empty}}
TextChanged =TextBox_TextChanged/>

查看codebehind:

  private void TextBox_TextChanged(object sender,TextChangedEventArgs e)
{
//删除安全转换和空检查
((TextBox)sender).GetBindingExpression(TextBox.TextProperty) .UpdateTarget();
}

ViewModel:

  private int?百分比; 
public int?百分比
{
get
{
return this.percentage;
}

set
{
if(this.Percentage == value)
{
return;
}

// Unset = 1
this.percentage = value? 1;

//强制介于1到100之间。
//使用TextBox,用户可能会尝试设置更大或更小的值。
if(this.Percentage< 1)
{
this.percentage = 1;
}
else if(this.Percentage> 100)
{
this.percentage = 100;
}
this.NotifyPropertyChanged(Percentage);
}
}

不幸的是,这个代码在.NET 4.0代码,简单地将TargetFramework更改为4.0)。具体来说,在我第一次强制该值之后,只要我继续输入整数值(因为我绑定到一个int),TextBox会忽略任何进一步的胁迫值。



所以如果我输入123,3之后我看到值100。现在如果我输入4,则ViewModel中的setter将获取值为1004,该值将强制为100.然后,TextChanged事件将被触发(发件人的TextBox.Text为100!),但TextBox显示 1004。如果我输入5,则设定器将获得值10045等。



如果我输入a,则文本框显示正确的值,即100。如果我继续输入数字,直到int溢出,同样的情况。



我如何解决这个问题?

解决方案

尝试在xaml中使用显式而不是PropertyChanged:

 < TextBox Text ={绑定百分比,模式= TwoWay,UpdateSourceTrigger =显式,TargetNullValue = {x:静态系统:String.Empty}}
TextChanged =TextBox_TextChanged/>

和UpdateSource代码,而不是UpdateTarget

  private void TextBox_TextChanged(object sender,TextChangedEventArgs e)
{
//删除安全转换和空检查
((TextBox)sender).GetBindingExpression (TextBox.TextProperty).UpdateSource();
}

测试它,它的工作原理。
Btw这个问题可能会在更高版本的.NET中解决。


In my WPF application I have a TextBox where the user can enter a percentage (as int, between 1 and 100). The Text property is databound to a property in a ViewModel, where I coerce the value to be in the given range in the setter.

However, in .NET 3.5, the data is not shown properly in the UI after being coerced. In this post on MSDN, Dr. WPF states that you have to manually update the binding so the correct will be shown. Therefore, I have a TextChanged handler (in the View) which calls UpdateTarget(). In code:

View XAML:

<TextBox Text="{Binding Percentage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static sys:String.Empty}}"
    TextChanged="TextBox_TextChanged"/>

View codebehind:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    // Removed safe casts and null checks
    ((TextBox)sender).GetBindingExpression(TextBox.TextProperty).UpdateTarget();
}

ViewModel:

private int? percentage;
public int? Percentage
{
    get
    {
        return this.percentage;
    }

    set
    {
        if (this.Percentage == value)
        {
            return;
        }

        // Unset = 1
        this.percentage = value ?? 1;

        // Coerce to be between 1 and 100.
        // Using the TextBox, a user may attempt setting a larger or smaller value.
        if (this.Percentage < 1)
        {
            this.percentage = 1;
        }
        else if (this.Percentage > 100)
        {
            this.percentage = 100;
        }
        this.NotifyPropertyChanged("Percentage");
    }
}

Unfortunately, this code breaks in .NET 4.0 (same code, simply changed TargetFramework to 4.0). Specifically, after I coerced the value for the first time, the TextBox ignores any further coerced values as long as I continue to enter integer values (since I am binding to an int).

So if I enter "123", after the 3 I see the value "100". Now if I enter "4", the setter in the ViewModel gets the value "1004", which it coerces to 100. The TextChanged event then fires (and the sender's TextBox.Text is "100"!), but the TextBox shows "1004". If I then enter "5", the setter gets the value "10045", etc.

If I then enter an "a", suddenly the TextBox shows the correct value, i.e. "100". The same occurs if I continue to enter numbers until the int overflows.

How can I fix this?

解决方案

Try using in xaml Explicit instead of PropertyChanged:

<TextBox Text="{Binding Percentage, Mode=TwoWay, UpdateSourceTrigger=Explicit, TargetNullValue={x:Static System:String.Empty}}"
             TextChanged="TextBox_TextChanged" />

and in code behind UpdateSource instead of UpdateTarget

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        // Removed safe casts and null checks
        ((TextBox)sender).GetBindingExpression(TextBox.TextProperty).UpdateSource();
    }

Tested it and it works. Btw this problem will probably be resolved in a later version of .NET.

这篇关于强制WPF TextBox在.NET 4.0中不再工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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