代码之家  ›  专栏  ›  技术社区  ›  Jacksonh

要使Silverlight中的自定义附加属性的属性元素语法正常工作,我需要做什么?

  •  4
  • Jacksonh  · 技术社区  · 17 年前

    我有一门课是这样的:

    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);
        }
    }
    

    <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>
    

    使用property元素语法,似乎完全忽略了我的set块(我甚至可以在其中放入无效的双精度值),并且永远不会调用SetStretchAmount方法。

    我知道这样做是可能的,因为VisualStateManager就是这么做的。我尝试过使用double以外的类型,但似乎没有任何效果。

    2 回复  |  直到 17 年前
        1
  •  2
  •   Bryant    17 年前

    我想我已经明白了这一点,尽管我不能完全确定我是否理解它起作用的原因。

    为了让您的示例正常工作,我必须创建一个名为Stretch的自定义类型,并使用一个名为StretchAmount的属性。一旦我这样做了,并把它放在属性元素标记中,它就工作了。否则就没人叫了。

    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); 
    }
    

    若要在不使用属性元素的情况下实现此功能,您需要创建一个自定义类型转换器以允许此功能。

    希望这能有所帮助,尽管它不能解释为什么我仍在努力理解。

    顺便说一句,要了解真正的脑筋急转弯,请查看reflector中的VisualStateManager。VisualStateGroup的dependency属性和setter都是 内部的 .

        2
  •  1
  •   Jacksonh    17 年前

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