附加属性不接受double的默认值

时间:2014-04-02 15:33:25

标签: c# wpf attached-properties xamlparseexception

我试图使用附加属性专门设置网格的左边距。 可悲的是,它不起作用。该属性抛出XamlParseException"默认值类型与属性类型"不匹配。

我的附属物

public class Margin : DependencyObject
{
    #region Dependency Properties
    public static readonly DependencyProperty LeftProperty =
        DependencyProperty.RegisterAttached("Left", typeof(double), typeof(Margin),
        new PropertyMetadata(new UIPropertyMetadata(0d, OnMarginLeftChanged)));
    #endregion

    #region Public Methods
    public static double GetLeft(DependencyObject obj)
    {
        return (double)obj.GetValue(LeftProperty);
    }
    public static void SetLeft(DependencyObject obj, double value)
    {
        obj.SetValue(LeftProperty, value);
    }
    #endregion

    #region Private Methods
    private static void OnMarginLeftChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var element = obj as FrameworkElement;
        var margin = element.Margin;
        margin.Left = (double)e.NewValue;
        element.Margin = margin;
    }
    #endregion
}

我的用户界面

<Window x:Class="MSPS.View.Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ctrl="clr-namespace:MSPS.View.Controls;assembly=MSPS.View.Controls"
        xmlns:ap="clr-namespace:MSPS.View.Controls.AttachedProperties;assembly=MSPS.View.Controls"
        Title="MainWindow" Height="350" Width="525">
    <Grid Background="Blue" ap:Margin.Left="20">

    </Grid>
</Window>

4 个答案:

答案 0 :(得分:2)

您未正确设置PropertyMetadata,在这种情况下,您需要两次创建此类的实例:

DependencyProperty.RegisterAttached("Left", typeof(double), typeof(Margin),
    new PropertyMetadata(new UIPropertyMetadata(0d, OnMarginLeftChanged)));

应该如此:

DependencyProperty.RegisterAttached("Left", typeof(double), typeof(Margin),
    new UIPropertyMetadata(0.0, OnMarginLeftChanged));

或者像这样:

DependencyProperty.RegisterAttached("Left", typeof(double), typeof(Margin),
    new PropertyMetadata(0d, OnMarginLeftChanged));

答案 1 :(得分:0)

我怀疑你的问题可能在这里:

private static void OnMarginLeftChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var element = obj as FrameworkElement;
    var margin = element.Margin;
    margin.Left = (double)e.NewValue;
    element.Margin = margin;
}

每个FrameworkElement都有Margin属性,其格式为框架Thickness。这是一个struct,包含4个double属性,LeftTopRightBottom

相反,请这样写:

private static void OnMarginLeftChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var element = obj as FrameworkElement;
    var margin = element.Margin;
    SetLeft( margin, (double)e.NewValue );
    element.Margin = margin;
}

这将设置您的附属财产。

那就是说,当框架已经提供了现有代码可以使用的属性时,为什么要使用Margins的附加属性?

答案 2 :(得分:0)

除非我误解,否则您的附加属性更改处理程序也会被调用默认值。尝试使用可空双。我不确定UIPropertyMetadata是否能为您带来任何好处 - 它具有一些特定于UI的属性,这可能是您的案例中的开销。尝试使用默认构造函数而不提供特定的元数据对象类型。

答案 3 :(得分:0)

DependencyProperty.RegisterAttached(“Left”,typeof(double),typeof(Margin),     new PropertyMetadata(0.0,OnMarginLeftChanged));