String DependencyProperty为Nullable

时间:2016-03-16 05:39:05

标签: c# dependency-properties

我想创建一个字符串DependencyProperty,它可以处理分配给可以为空的数字值(就像文本框TextProperty那样)。

我基本上复制了来自TextBox的反编译代码,并将其更改为我正在创建的DependencyProperty

[DefaultValue(null)]
//[DefaultValue(string.Empty)]
[Localizability(LocalizationCategory.Text)]
public string Number
{
    get { return (string)GetValue(NumberProperty); }
    set { SetValue(NumberProperty, value); }
} 

public static readonly DependencyProperty NumberProperty =
        DependencyProperty.Register(
                "Number", // Property name
                typeof(string), // Property type
                typeof(NumberControl), // Property owner 
                new FrameworkPropertyMetadata( // Property metadata
                        null, // default value 
                        //string.Empty, // default value
                        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | // Flags 
                            FrameworkPropertyMetadataOptions.Journal,
                        OnNumberPropertyChanged,    // property changed callback 
                        CoerceText,
                        true, // IsAnimationProhibited
                        UpdateSourceTrigger.PropertyChanged   // DefaultUpdateSourceTrigger
                        ));
private static object CoerceText(DependencyObject d, object value)
{
    var sv = value as string;
    if (sv == String.Empty) return null;
    return value;
    //if( value == null) return string.Empty;
}

private static void OnNumberPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var tb = (NumberControl) d;
    if (tb.Number != tb.Text)
    {
        tb.Text = tb.Number;
    }
}

但是,将此属性绑定到小数时?这是发生的例外

  

System.Windows.Data错误:7:ConvertBack无法转换值''(类型'String')。 BindingExpression:路径= DecimalProperty; DataItem ='MainWindowViewModel'(HashCode = 58431997); target元素是'NumberControl'(Name =''); target属性为'Number'(类型'String')FormatException:'System.FormatException:输入字符串的格式不正确。
  at System.Number.StringToNumber(String str,NumberStyles options,NumberBuffer& number,NumberFormatInfo info,Boolean parseDecimal)
  at System.Number.ParseDecimal(String value,NumberStyles options,NumberFormatInfo numfmt)
  在System.Convert.ToDecimal(字符串值,IFormatProvider提供者)
  在System.Convert.ChangeType(对象值,类型conversionType,IFormatProvider提供者)
  at System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter,Object value,Type sourceType,Object parameter,CultureInfo culture)'

注意:我尝试保留默认的string.empty行为,但这些行为无效,而我提供的代码尝试为null,但也无效

TextBox.Text是否有某种方式指定了其他默认转换器?

1 个答案:

答案 0 :(得分:2)

快速回答

您需要使用为DependancyProperty指定的null方法将PropertyChangedCallback直接设置为DependancyProperty,以便它不会使用默认转换器。

所以在我的情况下,OnNumberPropertyChanged方法被用作PropertyChangedCallback中需要调用的DependancyProperty

tb.SetValue(NumberProperty, null);

长答案

该死的我在发布问题后发现了questionanswer,这个问题并没有真正用我的搜索方式表达,直到我发布了#&# 34;默认转换器"在我的问题的最后。

我使用它的方法是在适当的时候使用代码手动将DependancyProperty值设置为null

    if (tb.Number == null)
    {
        tb.SetValue(NumberProperty, null);
    }

因此完整的OnNumberPropertyChanged方法是:

    /// <summary> 
    /// Callback for changes to the Number property 
    /// </summary>
private static void OnNumberPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var tb = (NumberControl) d;
    if (tb.Number != tb.Text)
    {
        tb.Text = tb.Number;
    }
    if (tb.Number == null)
    {
        tb.SetValue(NumberProperty, null);
    }
}