在不清除绑定的情况下使Silverlight 4自定义数字框为空
我正在尝试创建我自己的非常简单的NumberBox,它继承自TextBox,用于验证失去焦点时的输入,并根据指定的小数位设置值的格式。除非有人提出了一些无效的价值观,否则一切都很好 如果值无效,我希望将NumberBox设置为空,而不是0.0。将其重置为有效值(如0.0)将跳过代码中所需的字段验证检查 我尝试了此.Text=”“,但这会触发绑定异常“输入字符串格式不正确” 如果我尝试这个.ClearValue(TextProperty),它会清除文本框,但也会删除绑定。你知道如何实现这一点,或者除了工具箱之外,还有更好的NumberBox吗在不清除绑定的情况下使Silverlight 4自定义数字框为空,silverlight,silverlight-4.0,custom-controls,Silverlight,Silverlight 4.0,Custom Controls,我正在尝试创建我自己的非常简单的NumberBox,它继承自TextBox,用于验证失去焦点时的输入,并根据指定的小数位设置值的格式。除非有人提出了一些无效的价值观,否则一切都很好 如果值无效,我希望将NumberBox设置为空,而不是0.0。将其重置为有效值(如0.0)将跳过代码中所需的字段验证检查 我尝试了此.Text=”“,但这会触发绑定异常“输入字符串格式不正确” 如果我尝试这个.ClearValue(TextProperty),它会清除文本框,但也会删除绑定。你知道如何实现这一点,或者
public delegate void ValueChangedHandler(object sender, EventArgs args);
public class NumberBox : TextBox
{
public event ValueChangedHandler ValueChanged;
public NumberBox()
{
this.DefaultStyleKey = typeof(TextBox);
this.LostFocus += new RoutedEventHandler(NumberBox_LostFocus);
}
public static readonly DependencyProperty DecimalPlacesProperty = DependencyProperty.Register(
"DecimalPlaces",
typeof(int),
typeof(NumberBox),
new PropertyMetadata(2));
public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register(
"MaxValue",
typeof(double),
typeof(NumberBox),
new PropertyMetadata(Double.MaxValue));
public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register(
"MinValue",
typeof(double),
typeof(NumberBox),
new PropertyMetadata(0.0));
public int DecimalPlaces
{
get
{
return (int)this.GetValue(DecimalPlacesProperty);
}
set
{
base.SetValue(DecimalPlacesProperty, value);
}
}
public Double MaxValue
{
get
{
return (Double)this.GetValue(MaxValueProperty);
}
set
{
base.SetValue(MaxValueProperty, value);
}
}
public Double MinValue
{
get
{
return (Double)this.GetValue(MinValueProperty);
}
set
{
base.SetValue(MinValueProperty, value);
}
}
void NumberBox_LostFocus(object sender, RoutedEventArgs e)
{
double result;
//if (this.Text.Trim().Length == 0)
// return;
if (double.TryParse(this.Text, out result))
{
result = Math.Min(result, this.MaxValue);
result = Math.Max(result, this.MinValue);
this.Text = Math.Round(result, this.DecimalPlaces).ToString("N" + this.DecimalPlaces);
}
else
{
try
{
//this.Text = Math.Min(this.MinValue, 0.0).ToString();
this.ClearValue(TextBox.TextProperty);
}
catch
{
}
}
if (ValueChanged != null)
ValueChanged(this, EventArgs.Empty);
}
}
直接设置属性或调用ClearValue实际上会覆盖TextProperty上的任何内容,可以是BindingExpression。你真正想做的只是设置值,而不是真正改变其中的内容。听起来很混乱,整个DependencyProperty子系统都很复杂。基本上为以下内容替换ClearValue
this.SetValue(TextProperty, String.Empty)
你可以找到一个解释和答案。两者都适用于WPF,但相关。不过,UpdateTarget在Silverlight中不起作用(解决方案即将推出)
尽管如此,这种方法仍然存在缺陷。也就是说,您的源(绑定到的对象)仍将具有最新的有效值,即使根据您的UI,该值为。要解决这个问题,如果您在WPF中,只需调用UpdateTarget从源代码获取最新的有效值并更新目标(文本框)。Silverlight不支持这一点,但有一种讨厌的方法可以绕过这一限制:重新设置绑定
而不是ClearValue,您的代码将如下所示:
this.SetBinding(TextProperty, this.GetBindingExpression(TextProperty).ParentBinding);
if (double.TryParse(this.Text, out result))
{
result = Math.Min(result, this.MaxValue);
result = Math.Max(result, this.MinValue);
this.Text = Math.Round(result, this.DecimalPlaces).ToString("N" + this.DecimalPlaces);
}
最后一个块与方法的开头重复,因为在获得最新的有效值后,我们可能需要重新格式化字符串。也许值得创建一个方法来实现这一点
希望这有帮助
米格尔有很好的洞察力。我会试试,让你知道。这是我得到的最好答案