1

我正在尝试使用附加属性来专门设置网格的左边距。可悲的是,它不起作用。该属性引发 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

4 回答 4

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));
于 2014-04-02T15:38:07.717 回答
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属性、、Left和的a 。TopRightBottom

相反,这样写:

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 使用附加属性?

于 2014-04-02T15:41:27.643 回答
0

除非我弄错了,否则您的附加属性更改处理程序也会被调用为默认值。尝试使用可为空的双精度。我不确定 UIPropertyMetadata 是否会对您有任何好处 - 它具有一些特定于 UI 的属性,在您的情况下这可能是一种开销。尝试仅使用默认构造函数而不提供特定的元数据对象类型。

于 2014-04-02T15:52:32.083 回答
0

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

于 2016-03-21T15:46:03.517 回答