【问题标题】:What are the core properties of a UIElement in WPF?WPF 中 UIElement 的核心属性是什么?
【发布时间】:2013-06-10 18:52:42
【问题描述】:

根据 MSDN: 子 UIElement 首先测量其核心属性,从而开始布局过程。

评估在FrameworkElement 上定义的尺寸属性,例如宽度、高度和边距。

应用特定于面板的逻辑,例如 Dock 方向或堆叠方向。

内容是在所有孩子都被测量后安排的。

Children 集合被绘制在屏幕上。

如果向集合中添加了额外的 Children、应用了 LayoutTransform 或调用了 UpdateLayout 方法,则会再次调用该过程。

但是UIElement 的核心属性究竟是什么?

【问题讨论】:

    标签: c# wpf xaml uielement


    【解决方案1】:

    它所说的方法是MeasureCore,在文字UIElement类上它是这样实现的:

    protected virtual Size MeasureCore(Size availableSize)
    {
        return new Size(0.0, 0.0);
    }
    

    所以你可以看到它实际上对UIElement 没有任何作用。但是,在FrameworkElement 上,它是这样实现的:

    protected sealed override Size MeasureCore(Size availableSize)
    {
        bool useLayoutRounding = this.UseLayoutRounding;
        if (useLayoutRounding && !base.CheckFlagsAnd(VisualFlags.UseLayoutRounding))
        {
            base.SetFlags(true, VisualFlags.UseLayoutRounding);
        }
        this.ApplyTemplate();
        if (this.BypassLayoutPolicies)
        {
            return this.MeasureOverride(availableSize);
        }
        Thickness margin = this.Margin;
        double num = margin.Left + margin.Right;
        double num2 = margin.Top + margin.Bottom;
        if (useLayoutRounding && this is ScrollContentPresenter)
        {
            num = UIElement.RoundLayoutValue(num, FrameworkElement.DpiScaleX);
            num2 = UIElement.RoundLayoutValue(num2, FrameworkElement.DpiScaleY);
        }
        Size size = new Size(Math.Max(availableSize.Width - num, 0.0), Math.Max(availableSize.Height - num2, 0.0));
        FrameworkElement.MinMax minMax = new FrameworkElement.MinMax(this);
        FrameworkElement.LayoutTransformData layoutTransformData = FrameworkElement.LayoutTransformDataField.GetValue(this);
        Transform layoutTransform = this.LayoutTransform;
        if (layoutTransform != null && !layoutTransform.IsIdentity)
        {
            if (layoutTransformData == null)
            {
                layoutTransformData = new FrameworkElement.LayoutTransformData();
                FrameworkElement.LayoutTransformDataField.SetValue(this, layoutTransformData);
            }
            layoutTransformData.CreateTransformSnapshot(layoutTransform);
            layoutTransformData.UntransformedDS = default(Size);
            if (useLayoutRounding)
            {
                layoutTransformData.TransformedUnroundedDS = default(Size);
            }
        }
        else
        {
            if (layoutTransformData != null)
            {
                layoutTransformData = null;
                FrameworkElement.LayoutTransformDataField.ClearValue(this);
            }
        }
        if (layoutTransformData != null)
        {
            size = this.FindMaximalAreaLocalSpaceRect(layoutTransformData.Transform, size);
        }
        size.Width = Math.Max(minMax.minWidth, Math.Min(size.Width, minMax.maxWidth));
        size.Height = Math.Max(minMax.minHeight, Math.Min(size.Height, minMax.maxHeight));
        if (useLayoutRounding)
        {
            size = UIElement.RoundLayoutSize(size, FrameworkElement.DpiScaleX, FrameworkElement.DpiScaleY);
        }
        Size size2 = this.MeasureOverride(size);
        size2 = new Size(Math.Max(size2.Width, minMax.minWidth), Math.Max(size2.Height, minMax.minHeight));
        Size size3 = size2;
        if (layoutTransformData != null)
        {
            layoutTransformData.UntransformedDS = size3;
            Rect rect = Rect.Transform(new Rect(0.0, 0.0, size3.Width, size3.Height), layoutTransformData.Transform.Value);
            size3.Width = rect.Width;
            size3.Height = rect.Height;
        }
        bool flag = false;
        if (size2.Width > minMax.maxWidth)
        {
            size2.Width = minMax.maxWidth;
            flag = true;
        }
        if (size2.Height > minMax.maxHeight)
        {
            size2.Height = minMax.maxHeight;
            flag = true;
        }
        if (layoutTransformData != null)
        {
            Rect rect2 = Rect.Transform(new Rect(0.0, 0.0, size2.Width, size2.Height), layoutTransformData.Transform.Value);
            size2.Width = rect2.Width;
            size2.Height = rect2.Height;
        }
        double num3 = size2.Width + num;
        double num4 = size2.Height + num2;
        if (num3 > availableSize.Width)
        {
            num3 = availableSize.Width;
            flag = true;
        }
        if (num4 > availableSize.Height)
        {
            num4 = availableSize.Height;
            flag = true;
        }
        if (layoutTransformData != null)
        {
            layoutTransformData.TransformedUnroundedDS = new Size(Math.Max(0.0, num3), Math.Max(0.0, num4));
        }
        if (useLayoutRounding)
        {
            num3 = UIElement.RoundLayoutValue(num3, FrameworkElement.DpiScaleX);
            num4 = UIElement.RoundLayoutValue(num4, FrameworkElement.DpiScaleY);
        }
        SizeBox sizeBox = FrameworkElement.UnclippedDesiredSizeField.GetValue(this);
        if (flag || num3 < 0.0 || num4 < 0.0)
        {
            if (sizeBox == null)
            {
                sizeBox = new SizeBox(size3);
                FrameworkElement.UnclippedDesiredSizeField.SetValue(this, sizeBox);
            }
            else
            {
                sizeBox.Width = size3.Width;
                sizeBox.Height = size3.Height;
            }
        }
        else
        {
            if (sizeBox != null)
            {
                FrameworkElement.UnclippedDesiredSizeField.ClearValue(this);
            }
        }
        return new Size(Math.Max(0.0, num3), Math.Max(0.0, num4));
    }
    

    我知道要粘贴很多代码,但我这样做是为了说明一点。它很复杂——非常复杂——而且该方法可以被继承者覆盖以启动。

    在此代码示例中,您会看到诸如 WidthHeightMargin 之类的内容,以及更多用于衡量其核心的内容。

    【讨论】:

    • 酷!顺便说一句,你是怎么得到所有这些代码的?有时能看到一切似乎很有用
    • @JamesJoshuaStreet,我刚刚用 ILSpy 反编译了 .NET 源代码。
    【解决方案2】:

    但 UIElement 的核心属性究竟是什么?

    在这种情况下,“核心属性”将是影响布局的属性,例如VisibilityClipToBoundsVisualTransform,因为这些都会影响项目或其子项的布局过程.

    【讨论】:

    • 啊我还有一个问题。渲染是这样发生的吗?测量,排列,然后渲染?是什么导致渲染被调用?
    • @JamesJoshuaStreet 渲染是通过 DirectX 处理的 - 有关(很多)更多信息,请参阅:jeremiahmorrill.wordpress.com/2011/02/14/…
    【解决方案3】:

    您可以在 WPF 中查看UIElement 的核心属性列表

    http://msdn.microsoft.com/en-us/library/system.windows.uielement.aspx

    希望这能解释你...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 2010-10-31
      • 2021-08-13
      • 2016-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多