我需要做些什么才能使属性元素语法在Silverlight中为我的自定义附加属性工作?

时间:2008-11-11 20:35:33

标签: silverlight silverlight-2.0

我有一个这样的课程:

public class Stretcher : Panel {

    public static readonly DependencyProperty StretchAmountProp = DependencyProperty.RegisterAttached("StretchAmount", typeof(double), typeof(Stretcher), null);

    public static void SetStretchAmount(DependencyObject obj, double amount)
    {
        FrameworkElement elem = obj as FrameworkElement;
        elem.Width *= amount;

        obj.SetValue(StretchAmountProp, amount);
    }
}

我可以使用属性语法在XAML中设置拉伸量属性:

<UserControl x:Class="ManagedAttachedProps.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:map="clr-namespace:ManagedAttachedProps"
    Width="400" Height="300">

    <Rectangle Fill="Aqua" Width="100" Height="100" map:Stretch.StretchAmount="100" />

</UserControl>

我的矩形被拉伸了,但是我不能像这样使用属性元素语法:

<UserControl x:Class="ManagedAttachedProps.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:map="clr-namespace:ManagedAttachedProps"
    Width="400" Height="300">

    <Rectangle Fill="Aqua" Width="100" Height="100">
        <map:Stretcher.StretchAmount>100</map:Stretcher.StretchAmount>
    </Rectangle>
</UserControl>

使用属性元素语法我的set block似乎完全被忽略(我甚至可以在其中放置无效的double值),并且永远不会调用SetStretchAmount方法。

我知道可以做这样的事情,因为VisualStateManager做到了。我尝试过使用除double之外的其他类型,似乎没什么用。

2 个答案:

答案 0 :(得分:2)

我想我想出来了,虽然我不完全确定我理解它起作用的原因。

为了让你的例子起作用,我必须使用一个名为StretchAmount的属性创建一个名为Stretch的自定义类型。一旦我这样做并将其放在属性元素标签内就可以了。否则它没有被调用。

public class Stretch
{
    public double StretchAmount { get; set; }
}

该财产改为..

public static readonly DependencyProperty StretchAmountProp = DependencyProperty.RegisterAttached("StretchAmount", typeof(Stretch), typeof(Stretcher), null);

public static void SetStretchAmount(DependencyObject obj, Stretch amount) 
{ 
    FrameworkElement elem = obj as FrameworkElement; 
    elem.Width *= amount.StretchAmount; 
    obj.SetValue(StretchAmountProp, amount); 
}

要在不使用属性元素的场景中使其工作,您需要创建一个自定义类型转换器以允许它工作。

希望这会有所帮助,即使它没有解释为什么我仍然试图理解。

BTW - 对于真正的脑筋急转弯,请查看反射器中的VisualStateManager。依赖项属性和VisualStateGroups的setter都是 internal

答案 1 :(得分:1)

因此,布莱恩特的解决方案有效,它确实需要对XAML稍作修改:

<Rectangle Fill="Aqua" Width="100" Height="100" x:Name="the_rect">
        <map:Stretcher.StretchAmount>
            <map:Stretch StretchAmount="100" />
        </map:Stretcher.StretchAmount>
</Rectangle>