4

我有这样的课:

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 块似乎完全被忽略了(我什至可以在其中放置无效的双精度值),并且永远不会调用 SetStretchAmount 方法。

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

4

2 回答 2

2

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

为了让您的示例正常工作,我必须创建一个名为 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); 
}

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

希望这会有所帮助,即使它没有解释我仍在努力理解的原因。

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

于 2008-11-11T22:49:46.790 回答
1

所以 Bryant 的解决方案有效,它确实需要对 XAML 稍作修改:

<Rectangle Fill="Aqua" Width="100" Height="100" x:Name="the_rect">
        <map:Stretcher.StretchAmount>
            <map:Stretch StretchAmount="100" />
        </map:Stretcher.StretchAmount>
</Rectangle>
于 2008-11-12T15:19:04.907 回答