未调用文本框值的绑定属性> 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。
答案 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。