代码之家  ›  专栏  ›  技术社区  ›  Daniel Rose

强制WPF文本框在.NET 4.0中不再工作

  •  5
  • Daniel Rose  · 技术社区  · 14 年前

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

    但是,在.NET 3.5中,数据在被强制之后没有在UI中正确显示。在 this post on MSDN ,wpf博士说您必须手动更新绑定,以便显示正确的绑定。因此,我有一个 TextChanged 调用的处理程序(在视图中) UpdateTarget() . 在代码中:

    查看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),文本框就会忽略任何其他强制值。

    因此,如果我输入“123”,在3之后,我会看到值“100”。现在,如果我输入“4”,viewModel中的setter将得到值“1004”,它将强制为100。然后引发TextChanged事件(发送方的文本框。文本为“100”!)但文本框显示“1004”。如果我输入“5”,那么setter将得到值“10045”等。

    如果输入“A”,文本框会突然显示正确的值,即“100”。如果我继续输入数字直到int溢出,也会发生同样的情况。

    我怎么修这个?

    2 回复  |  直到 8 年前
        1
  •  3
  •   RonaldV    14 年前

    尝试在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的较新版本中得到解决。

        2
  •  0
  •   bob12312312    8 年前

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