在.NET 4.0中,强制转换WPF TextBox不再起作用。

6
在我的WPF应用程序中,我有一个文本框,用户可以输入一个百分比(作为int类型,介于1和100之间)。Text属性与ViewModel中的一个属性进行了数据绑定,在setter中我强制将值限制在给定范围内。
然而,在.NET 3.5中,经过强制后,数据在UI中显示不正确。在MSDN上的这篇文章中,Dr. WPF指出,您必须手动更新绑定,以便正确显示。因此,我在View中有一个TextChanged处理程序,调用UpdateTarget()方法。代码如下:
View XAML:
<TextBox Text="{Binding Percentage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, TargetNullValue={x:Static sys:String.Empty}}"
    TextChanged="TextBox_TextChanged"/>

查看代码后台:

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");
    }
}

很不幸,这个代码在.NET 4.0中出现问题(同样的代码,只是将TargetFramework更改为4.0)。具体来说,在我第一次强制转换值后,只要我继续输入整数值(因为我绑定到一个int),TextBox就会忽略任何进一步的强制转换值。
因此,如果我输入“123”,在3之后我看到的值是“100”。现在,如果我输入“4”,ViewModel中的setter获取到值“1004”,它被强制转换为100。然后TextChanged事件触发(发送者的TextBox.Text为“100”!),但TextBox显示为“1004”。如果我接着输入“5”,setter获取到值“10045”,以此类推。
如果我然后输入一个“a”,突然TextBox显示正确的值,即“100”。如果我继续输入数字直到int溢出,也会出现相同的情况。
我该如何解决这个问题?
2个回答

4
尝试在XAML中使用Explicit而不是PropertyChanged:
<TextBox Text="{Binding Percentage, Mode=TwoWay, UpdateSourceTrigger=Explicit, TargetNullValue={x:Static System:String.Empty}}"
             TextChanged="TextBox_TextChanged" />

在代码后端使用UpdateSource而不是UpdateTarget

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

我已经测试过它,它可以工作。顺便说一下,这个问题可能会在以后的 .NET 版本中解决。


感谢您的帮助。使用 UpdateSourceTrigger=PropertyChanged,这对我很有效。 - ergohack

0

您可以使用PropertyChanged。但是,请尝试绑定到EditValueProperty依赖项,而不是TextProperty依赖项(或事件)。它将按预期工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接