从CustomPanel更改附加属性不会刷新面板

时间:2018-01-22 09:13:17

标签: c# wpf xaml wpf-controls propertychanged

我创建了虚拟自定义面板ShelfPanel,其附加属性Exact影响面板排列:

class ShelfPanel : Panel
{
    #region Start attached property
    public static DependencyProperty ExactProperty = DependencyProperty.RegisterAttached("Exact", typeof(int), typeof(ShelfPanel),
        new FrameworkPropertyMetadata(0, 
            FrameworkPropertyMetadataOptions.AffectsArrange | // Does this options have auto action?
            FrameworkPropertyMetadataOptions.AffectsRender)); // Does this options have auto action?

    public static void SetExact(UIElement element, int value)
    {
        element.SetValue(ExactProperty, value);
    }

    public static int GetExact(UIElement element)
    {
        return (int)element.GetValue(ExactProperty);
    }
    #endregion

    protected override Size MeasureOverride(Size availableSize)
    {
        Size final = new Size();
        foreach (UIElement child in InternalChildren)
        {
            child.Measure(availableSize);
            final.Height += child.DesiredSize.Height;
        }
        return final;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        foreach (UIElement child in InternalChildren)
        {
            Point position = new Point();
            int exact = ShelfPanel.GetExact(child);
            // Calculate position based on attached Exact
            position.X = exact * 100;
            position.Y = exact * 100;
            child.Arrange(new Rect(position, child.DesiredSize));
        }
        return finalSize;
    }
}
<local:ShelfPanel>
     <local:Box local:ShelfPanel.Exact="0" MouseDown="Box_MouseDown"/>
     <local:Box local:ShelfPanel.Exact="1" />
     <local:Box local:ShelfPanel.Exact="2" />
</local:ShelfPanel>
public partial class MainWindow : Window // Codebehind for previous xaml
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Box_MouseDown(object sender, MouseButtonEventArgs e)
    {
        // I certainly sure this code get triggered after click.
        ShelfPanel.SetExact(sender as UIElement, 3); 
    }
}

这项完美<local:Box>工作按计划安排。 正如您可以从代码中推断出来的,在点击第一个<local:Box>后,它应该将其位置更改为3,就在其他人之后2.但令人惊讶的是没有任何事情发生。

没有FrameworkPropertyMetadataOptions.Affects ArrangeFrameworkPropertyMetadataOptions.AffectsRender自动重新粉饰小组吗? 要实现此功能,我需要添加PropertyChangedCallback并在其中调用InvalidateVisual()

1 个答案:

答案 0 :(得分:1)

您正在Box上设置附加属性,但需要Box的父元素,即ShelfPanel。

因此,您应该设置FrameworkPropertyMetadataOptions.AffectsParentArrange

public static readonly DependencyProperty ExactProperty =
    DependencyProperty.RegisterAttached("Exact", typeof(int), typeof(ShelfPanel),
        new FrameworkPropertyMetadata(0,
            FrameworkPropertyMetadataOptions.AffectsParentArrange));