【问题标题】:Attached property being reset in designer view在设计器视图中重置附加属性
【发布时间】:2025-11-27 05:40:01
【问题描述】:

我有一个网格的附加属性。它用于自动布置 Grid 内的内容控件。基本上所做的是,它通过 Children 集合并将每个控件放在 Grid 控件的下一个空闲单元格中。它只完成一次(在 Initialized 事件处理程序中)。

    public static readonly DependencyProperty AutoLayoutProperty =
        DependencyProperty.RegisterAttached(
            "AutoLayout", 
            typeof(bool), 
            typeof(GridEx), 
            new UIPropertyMetadata(false, OnAutoLayoutChanged));

    private static void OnAutoLayoutChanged(
        DependencyObject d, 
        DependencyPropertyChangedEventArgs e)
    {
        var grid = d as Grid;
        if (!grid.IsInitialized) 
            grid.Initialized += new EventHandler(grid_Initialized);
        else { UpdateLayout(grid); }
    }
    private static void UpdateLayout(Grid grid)
    {
        foreach(var child in grid.Children) 
        {
            // Set Grid.Column and Grid.Row properties on the child
        }
    }

此代码可以正常工作并且可以满足我的所有需求,但存在一个问题 - 当我在 Expression Blend 设计器中编辑网格的内容时,子控件上的 Grid.Column 和 Grid.Row 属性会被重置。这很烦人。如何检测 Blend 设计器的刷新并将这些附加属性重新应用到网格子级?

【问题讨论】:

    标签: wpf layout grid designer attached-properties


    【解决方案1】:

    尝试使用Loaded 事件。

    编辑 - 为设计师添加了解决方法

    private static void OnAutoLayoutChanged(
        DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        var grid = d as Grid;            
        grid.Loaded += (object sender, RoutedEventArgs e2) =>
        {
            UpdateLayout(grid);
        };
    
        // Workaround for Blend..
        if (DesignerProperties.GetIsInDesignMode(grid) == true)
        {
            grid.LayoutUpdated += (object sender, EventArgs e2) =>
            {
                UpdateLayout(grid);
            };
        }
    }
    

    【讨论】:

    • 不幸的是,这没有帮助。只要我例如删除网格内的控件,所有其他子项在设计器中重置为 Grid.Row=0 和 Grid.Column=0。
    • @Jefim:我明白你的意思。我为设计师添加了一个解决方法。看看它是否适合你