Reputation: 437
I'm trying to use an attached property to set the left margin of a grid exclusively. Sadly, it doesn't work. The property throws a XamlParseException "Default value type does not match type of property".
My attached property
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
}
My user Interface
<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>
Upvotes: 1
Views: 1426
Reputation: 525
DependencyProperty.RegisterAttached("Left", typeof(double), typeof(Margin), new PropertyMetadata(0.0, OnMarginLeftChanged));
Upvotes: 0
Reputation: 22702
You not correctly set PropertyMetadata
, in this case you two times create the instance of this class:
DependencyProperty.RegisterAttached("Left", typeof(double), typeof(Margin),
new PropertyMetadata(new UIPropertyMetadata(0d, OnMarginLeftChanged)));
Should be so:
DependencyProperty.RegisterAttached("Left", typeof(double), typeof(Margin),
new UIPropertyMetadata(0.0, OnMarginLeftChanged));
Or like this:
DependencyProperty.RegisterAttached("Left", typeof(double), typeof(Margin),
new PropertyMetadata(0d, OnMarginLeftChanged));
Upvotes: 3
Reputation: 161
Your attached property change handler gets called for the default value too unless I'm mistaken. Try using nullable double. I'm not sure if UIPropertyMetadata will do you any good - it has some UI specific properties, which might be an overhead in your case. Try using just default constructor without giving a specific Metadata object type.
Upvotes: 0
Reputation: 8614
I suspect that your problem may be in here:
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;
}
Every FrameworkElement
has a Margin
property that has the Framework Thickness
type. This is a struct
with 4 double
properties, Left
, Top
, Right
and Bottom
.
Instead, write it like this:
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;
}
That will set your attached property.
That said, why are you using an attached property for Margins when the framework already provides a property that your existing code would work with?
Upvotes: 0