未为文本框值调用绑定属性>;int.MaxValue

本文关键字:gt int MaxValue 属性 绑定 文本 值调用 | 更新日期: 2023-09-27 18:29:52

未为textbox值>int.MaxValue 调用绑定属性

如果输入的值大于int.MaxValue,我需要恢复到文本框中的最后一个值。请参阅下面的代码。

主窗口.xaml

<Window x:Class="SampleWPFApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBox Text="{Binding Count, UpdateSourceTrigger=LostFocus}" />
        <Button Content="Click!" Width="100" Height="50"/>
    </StackPanel>
</Window>

主窗口.xaml.cs

using System.Windows;
namespace SampleWPFApplication
{
     /// <summary>
     /// Interaction logic for MainWindow.xaml
     /// </summary>
     public partial class MainWindow : Window
     {
         public MainWindow()
         {
             InitializeComponent();
             this.DataContext = this;
         }
         private int _count = 32;
     public int Count
         {
            get { return _count;}
            set 
            {
                if(value <= int.MaxValue)
                    _count = value;
            }
         }
     }
}

在Count属性的setter处设置断点。对于小于int.MaxValue的值,会命中此断点。在我的系统中,int.Maxvalue的值为2147483647。如果您给出的值大于这个值,断点将不会命中,文本框将被红色矩形包围。对于超出范围的值,我想在文本框中恢复到以前的值。

如果我用不等于int.MaxValue(例如999)的值替换上面属性setter中的int.MaxValue,它就可以正常工作。我相信textbox内部有一个最大值为int.MaxValue,当给出一个大于这个值的值时,它会进行自己的验证,验证失败,绑定也不会更新。

我已经在xaml中设置了PresentationTraceSources.TraceLevel=High,如链接中所述http://blogs.msdn.com/b/wpfsldesigner/archive/2010/06/30/debugging-data-bindings-in-a-wpf-or-silverlight-application.aspx并得到StackOverFlowException。

System.Windows.Data警告:95:BindingExpression(hash=52085517):从TextBox(hash=10223660)System.Windows.Data获取LostFocus事件警告:90:BindingExpression(hash=52085517):更新-获取原始值"2147483649"SampleWPFApplication.vshost.exe"(托管(v4.0.30319)):已加载"C:''Windows''Microsoft.Net''assembly''GAC_MSIL''PresentationFrame SystemData''v4.0_4.0.0.0__b77a5c561934e089''Presentation框架系统数据.dll",已跳过加载符号。模块已优化,调试器选项"仅我的代码"已启用。System.Windows.Data错误:7:ConvertBack无法转换值"2147483649"(类型为"String")。BindingExpression:Path=Count;DataItem='MainWindow'(名称='');目标元素为"TextBox"(名称=");目标属性为"Text"(类型"String")OverflowException:"System.OverflowException:值为对于Int32来说太大或太小。在System.Number.ParseInt32(字符串s,NumberStyles样式,NumberFormatInfo信息)System.String.System.IConvertible.ToInt32(IFormatProvider提供程序)
在System.Convert.ChangeType(Object value,Type conversionType,IFormatProvider提供程序)MS.Internal.Data.SystemConverter.ConvertBack(对象o,类型类型,Object参数,CultureInfo区域性)System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverterconverter,Object值,Type sourceType,Object参数,CultureInfo区域性)的System.Windows.Data警告:93:BindingExpression(hash=52085517):更新-隐式转换器生成了{DependencyProperty.UnsetValue}System.Windows.Data警告:94:BindingExpression(hash=52085517):更新-使用最终值{DependencyPropertyUnsetValue}

有人能解释这种行为以及克服这种行为的方法吗。?此外,有没有一种方法可以覆盖RED矩形行为?

类似的问题(TextBox-使用IDataErrorInfo进行验证的问题,其整数值大于int.MaxValue(2147483647)),没有解决方案

解决方法:一种解决方法是将属性的数据类型从int更改为long。

未为文本框值调用绑定属性>;int.MaxValue

您无法访问Setter的原因是WPF的自动绑定验证过程已经停止(IsValid=false),这就是您想要的整数不能大于int.MaxValue。它基本上已经事先询问了您的Setter在问什么,然后在失败时显示ErrorTemplate

您可以更改ErrorTemplate。这会在文本框周围设置一个橙色边框,并显示报告的错误消息。

<TextBox Text="{Binding Count, UpdateSourceTrigger=LostFocus}">
        <Validation.ErrorTemplate>
            <ControlTemplate>
                <StackPanel>
                    <!-- Placeholder for the TextBox itself -->
                    <Border BorderBrush="Orange" BorderThickness="2">
                        <AdornedElementPlaceholder x:Name="textBox"/>
                    </Border>
                    <TextBlock Text="{Binding [0].ErrorContent}" Foreground="Green"/>
                </StackPanel>
            </ControlTemplate>
        </Validation.ErrorTemplate>
      </TextBox>

这是一篇关于这种行为的非常好的文章

不调用setter的原因是,在设置属性之前,绑定首先将值转换为适当的类型(在这种情况下,string转换为int)。由于2147483649不是有效的int值(它大于int.MaxValue),转换失败,绑定中止源更新。在这种情况下,正如@dellywheel在回答中提到的那样,绑定的IsValid属性设置为false,错误模板显示在文本框中。

实现所描述行为的一种方法是定义一个代理属性,该属性将负责验证/转换并绑定到它,而不是Count属性。这里有一个例子:

public string CountProxy
{
    get { return Count.ToString(); }
    set
    {
        int n;
        if (int.TryParse(value, out n) && n <= MaxValue)
            Count = n;
    }
}

如果MaxValue将是int.MaxValue,则可以跳过比较,因为对于所有超出范围的值,int.TryParse都将返回false。