首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么不启动MeasureOverride?

为什么不启动MeasureOverride?
EN

Stack Overflow用户
提问于 2017-05-11 13:26:20
回答 1查看 88关注 0票数 0

我有两个自定义控件,用于显示注释和签名集合。每个控件都有一个按钮,用于更改显示样式--显示整个集合或仅显示前4个元素。

当我将这些控件放在默认的WrapPanel中时,它们可以正常工作:根据用户的操作展开或折叠。在我自己定制的带有新WrapPanel函数的ArrangeOverride中,它们也可以正常工作。

现在,我需要WrapPanel和选项"LastChildFill“(我在这里找到了示例)和自定义"WrapDirection”(类似于FlowDirection)。WrapPanel中的第一个或最后一个元素必须填充所有剩余的空间,而不是元素的MinWidth。因此,我创建了带有自定义MeasureOverride和ArrangeOverride的第三个MeasureOverride。它可以按我的意愿工作,但当我更改控件显示样式时,控件中的集合会发生变化,但在更改窗口大小之前,MeasureOverride在我的WrapPanel中才会启动。

更新: MeasureOverride不开始展开第一个或最后一个元素,以填充剩余空间。这个元素的折叠很好。

我不明白我用定制的MeasureOverride打破了什么?

更新2:我认为我的问题类似于:MeasureOverride not always called on children's property changes

并附加MeasureOverride代码。

代码语言:javascript
复制
public class WrapPanelFlowDirection : WrapPanel
{
    public bool LastChildFill
    {
        get { return (bool)GetValue(LastChildFillProperty); }
        set { SetValue(LastChildFillProperty, value); }
    }

    public static readonly DependencyProperty LastChildFillProperty =
        DependencyProperty.Register("LastChildFill", typeof(bool), typeof(WrapPanelFlowDirection), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsMeasure));

    public WrapDirection WrapDirection
    {
        get { return (WrapDirection)GetValue(WrapDirectionProperty); }
        set { SetValue(WrapDirectionProperty, value); }
    }

    public static readonly DependencyProperty WrapDirectionProperty =
        DependencyProperty.Register("WrapDirection", typeof(WrapDirection), typeof(WrapPanelFlowDirection), new FrameworkPropertyMetadata(WrapDirection.LeftToRight, FrameworkPropertyMetadataOptions.AffectsMeasure));

    #region Measure Override

    protected override Size MeasureOverride(Size availableSize)
    {
        var panelSize = new Size(availableSize.Width, 0);
        double minWidth = 0;

        foreach (FrameworkElement child in this.InternalChildren)
        {
            child.Measure(availableSize);
            minWidth += child.DesiredSize.Width;
        }

        int firstChildInLine = 0;
        double currLineHeight = 0;
        double currLineWidth = 0;
        UIElementCollection children = this.InternalChildren;

        for (int i = 0; i < children.Count; i++)
        {
            FrameworkElement child = children[i] as FrameworkElement;
            if (child == null)
                continue;

            double w = 0;
            if (child.MinWidth == 0)
                w = child.DesiredSize.Width;
            else
                w = child.MinWidth;

            if (currLineWidth + w <= availableSize.Width)
            {
                currLineWidth += w;
                currLineHeight = Math.Max(currLineHeight, child.DesiredSize.Height);
            }
            else
            {
                MeasureOneLine(firstChildInLine, i - 1, ref currLineHeight, availableSize.Width);
                panelSize.Height += currLineHeight;
                currLineWidth = w;
                currLineHeight = child.DesiredSize.Height;
                if (w > availableSize.Width)
                {
                    MeasureOneLine(i, i, ref currLineHeight, availableSize.Width);
                    panelSize.Height += currLineHeight;
                    currLineHeight = currLineWidth = 0;
                    firstChildInLine = i + 1;
                }
                else
                {
                    firstChildInLine = i;
                }
            }

        }

        if (firstChildInLine < children.Count)
        {
            MeasureOneLine(firstChildInLine, children.Count - 1, ref currLineHeight, availableSize.Width);
            panelSize.Height += currLineHeight;
        }

        if (double.IsInfinity(panelSize.Width))
            panelSize.Width = minWidth;
        return panelSize;
    }

    private void MeasureOneLine(int start, int end, ref double height, double totalWidth)
    {
        UIElementCollection children = this.InternalChildren;

        if (WrapDirection == WrapDirection.LeftToRight)
        {
            for (int i = start; i < end; i++)
            {
                FrameworkElement child = children[i] as FrameworkElement;
                if (child == null)
                    continue;

                double w = 0;
                if (child.MinWidth == 0)
                    w = child.DesiredSize.Width;
                else
                    w = child.MinWidth;
                if (i < end)
                {
                    child.Measure(new Size(w, height));
                    totalWidth -= w;
                }
                else
                {
                    child.Measure(new Size(totalWidth, double.PositiveInfinity));
                    height = Math.Max(height, child.DesiredSize.Height);
                }
            }
        }
        else
        {
            for (int i = end; i >= start; i--)
            {
                FrameworkElement child = children[i] as FrameworkElement;
                if (child == null)
                    continue;

                double w = 0;
                if (child.MinWidth == 0)
                    w = child.DesiredSize.Width;
                else
                    w = child.MinWidth;
                if (i > start)
                {
                    child.Measure(new Size(w, height));
                    totalWidth -= w;
                }
                else
                {
                    child.Measure(new Size(totalWidth, double.PositiveInfinity));
                    height = Math.Max(height, child.DesiredSize.Height);
                }
            }
        }
    }

    #endregion
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-12 15:00:07

我在这里找到了解决方案:How does a container know when a child has called InvalidateArrange?

对我来说很管用。

代码语言:javascript
复制
    public static void OnPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        UIElement panel= VisualTreeHelper.GetParent(source) as UIElement;
        if(panel != null)       
            {
                panel.InvalidateMeasure();
                panel.InvalidateArrange();
            }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43916815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档