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

时间:2014-11-10 04:13:46

标签: c# wpf xaml

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

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

MainWindow.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>

MainWindow.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。如果给出大于此值的值,则不会触发断点,并且文本框被红色矩形包围。 我想在文本框中恢复到超出范围值的先前值。

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

我已按照链接http://blogs.msdn.com/b/wpfsldesigner/archive/2010/06/30/debugging-data-bindings-in-a-wpf-or-silverlight-application.aspx中的说明在xaml中设置了PresentationTraceSources.TraceLevel = High 得到了StackOverFlowException。

  

System.Windows.Data警告:95:BindingExpression(hash = 52085517):   从TextBox获得LostFocus事件(hash = 10223660)System.Windows.Data   警告:90:BindingExpression(hash = 52085517):更新 - 得到原始   值'2147483649''SampleWPFApplication.vshost.exe'(管理   (v4.0.30319)):已加载   'C:\的Windows \ Microsoft.Net \组件\ GAC_MSIL \ PresentationFramework-SystemData \ v4.0_4.0.0.0__b77a5c561934e089 \ PresentationFramework-SystemData.dll',   跳过加载符号。模块已优化并具有调试器选项   'Just My Code'已启用。 System.Windows.Data错误:7:ConvertBack   无法转换值'2147483649'(类型'字符串')。   BindingExpression:路径=计数; DataItem ='MainWindow'(Name ='');目标   element是'TextBox'(Name =''); target属性是'Text'(类型   'String')OverflowException:'System.OverflowException:Value is   对于Int32来说太大或太小。在   System.Number.ParseInt32(String s,NumberStyles样式,   NumberFormatInfo信息)at   System.String.System.IConvertible.ToInt32(IFormatProvider provider)
  在System.Convert.ChangeType(对象值,类型conversionType,   IFormatProvider提供商)   MS.Internal.Data.SystemConvertConverter.ConvertBack(Object o,Type   type,Object parameter,CultureInfo culture)at   System.Windows.Data.BindingExpression.ConvertBackHelper(的IValueConverter   converter,Object value,Type sourceType,Object parameter,   '文化信息文化)'System.Windows.Data警告:93:   BindingExpression(hash = 52085517):更新 - 隐式转换器   生成{DependencyProperty.UnsetValue} System.Windows.Data警告:   94:BindingExpression(hash = 52085517):更新 - 使用最终值   {DependencyProperty.UnsetValue}

有人可以解释这种行为和方式吗? 另外,有没有办法覆盖RED矩形行为?

类似问题(TextBox - Issue with validation using IDataErrorInfo with integer Value more than int.MaxValue (2147483647))没有解决方案

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

2 个答案:

答案 0 :(得分:0)

您无法访问Setter的原因是WPF的自动绑定验证过程已停止(IsValid = false),这是您想要的,因为Integer不能大于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>

Here是关于此行为的非常好的文章

答案 1 :(得分:0)

未调用setter的原因是在设置属性之前,该值首先由绑定转换为适当的类型(在这种情况下,string将转换为int)。由于2147483649不是有效的int值(它大于int.MaxValue),因此转换失败,绑定将中止源更新。在这种情况下,正如@dlywheel在他/她的回答中提到的,绑定的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。