Подтвердить что ты не робот

Stackpanel: высота против ActualHeight против ExtentHeight против ViewportHeight против DesiredSize vs RenderSize

Я хочу знать высоту всех элементов my StackPanel.

В чем разница между:

  • Height - Получает или задает рекомендуемую высоту элемента.
  • ActualHeight - Получает визуализированную высоту этого элемента. (Только для чтения)
  • ExtentHeight - Получает значение, которое содержит вертикальный размер. (Только для чтения)
  • ViewportHeight - Получает значение, которое содержит вертикальный размер окна просмотра контента. (Только для чтения)
  • DesiredSize - Получает размер, который этот элемент вычислял во время прохождения измерения процесса компоновки. (Только для чтения)
  • RenderSize - Получает (или задает, но видит Заметки) окончательный размер рендеринга этого элемента.

Из MSDN:

Height
Получает или задает рекомендуемую высоту элемента.

Значение свойства: Double - высота элемента в единицах, не зависящих от устройства (1/96-дюймовый дюйм на единицу).

Высота элемента в единицах, не зависящих от устройства (1/96-й дюйм на единицу).

 

ActualHeight (только для чтения)
Получает визуализированную высоту этого элемента.

Значение свойства: Double - высота элемента, как значение в единицах, не зависящих от устройства (1/96-й дюйм на единицу).

Это свойство представляет собой рассчитанное значение, основанное на других входах высоты и системе компоновки. Значение устанавливается самой компоновкой, основанной на фактическом проходе рендеринга, и поэтому может немного отставать от установленного значения свойств, таких как Height, которые являются основы изменения ввода.

Поскольку ActualHeight является рассчитанным значением, вы должны знать, что в результате различных операций с помощью системы макета могут быть множественные или инкрементные сообщенные изменения. Система компоновки может вычислять требуемое пространство измерения для дочерних элементов, ограничений родительским элементом и т.д.

 

ExtentHeight (только для чтения)
Возвращает значение, которое содержит вертикальный размер.

Высота свойства: Double - Двойной, который представляет вертикальный размер степени.

Возвращаемое значение описано в разделе Независимые устройства.

 

ViewportHeight (только для чтения)
Возвращает значение, которое содержит вертикальный размер окна просмотра содержимого.

Значение свойства: Double - Double, представляющее вертикальный размер окна просмотра содержимого.

Возвращаемое значение описано в разделе Независимые устройства.

 

DesiredSize (только для чтения)
Получает размер, который этот элемент вычисляет во время прохождения измерения процесса компоновки.

Значение свойства: Size - Вычисленный размер, который становится желаемым размером для аранжировки.

Значение, возвращаемое этим свойством, будет действительным только в том случае, если значение свойства IsMeasureValid истинно.

DesiredSize обычно проверяется как один из факторов измерения при реализации переопределений поведения компоновки, таких как ArrangeOverride, MeasureOverride или OnRender (в случае OnRender вы можете проверить RenderSize, но это зависит от вашей реализации). В зависимости от сценария DesiredSize может полностью соблюдаться вашей логикой реализации, могут применяться ограничения на DesiredSize, и такие ограничения могут также изменять другие характеристики либо родительского элемента, либо дочернего элемента. Например, элемент управления, который поддерживает области с возможностью прокрутки (но не выбирает из элементов управления уровня WPF, которые уже позволяют прокручиваемые области), может сравнивать доступный размер с DesiredSize. Затем элемент управления мог установить внутреннее состояние, которое позволяло использовать полосы прокрутки в пользовательском интерфейсе для этого элемента управления. Или, DesiredSize потенциально также может быть проигнорирован в определенных сценариях.

 

RenderSizeПолучает окончательный размер рендеринга этого элемента.

Значение свойства: Size - размер рендеринга для этого элемента.

Это свойство может использоваться для проверки применимого размера рендеринга в рамках переопределения системы компоновки, таких как OnRender или GetLayoutClip.

Более распространенный сценарий обрабатывает событие SizeChanged с переопределением обработчика класса или событием OnRenderSizeChanged.


В моем случае я хочу знать высоту желаемую всех элементов в StackPanel.

Другими словами: я хочу знать высоту всех элементов в StackPanel (перед рисованием), и если они должны были переполнять панель, я буду

  • удалить
  • термоусадочная
  • Масштаб
  • настроить

чтобы они соответствовали стилю StackPanel.

Что означает, что я, вероятно, хочу получить желаемую высоту (ExtentHeight? DesiredSize?) во время события изменения размера (SizeChanged? LayoutUpdated?) - до того, как произойдет какой-либо рисунок (так быстрее).

Большинство этих свойств возвращают ноль; поэтому очевидно, что существует некоторое понимание того, что означают эти свойства, которые я не знаю и не объяснены в документации.

4b9b3361

Ответ 1

Как вы знаете, StackPanel является объектом [Panel]. Каждая панель связывается со своими детьми двумя способами, чтобы определить конечные размеры и позиции. Первый метод - MeasureOverride, второй - ArrangeOverride.

MeasureOveride запрашивает у каждого ребенка желаемый размер с заданным объемом свободного места. ArrangeOverride устраивает детей после завершения измерения.

Создайте пакетную панель:

public class AnotherStackPanel : Panel
{
    public static readonly DependencyProperty OrientationProperty =
        DependencyProperty.Register("Orientation", typeof(Orientation),
        typeof(SimpleStackPanel), new FrameworkPropertyMetadata(
        Orientation.Vertical, FrameworkPropertyMetadataOptions.AffectsMeasure));

    public Orientation Orientation
    {
        get { return (Orientation)GetValue(OrientationProperty); }
        set { SetValue(OrientationProperty, value); }
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        Size desiredSize = new Size();

        if (Orientation == Orientation.Vertical)
            availableSize.Height = Double.PositiveInfinity;
        else
            availableSize.Width = Double.PositiveInfinity;
        foreach (UIElement child in this.Children)
        {
            if (child != null)
            {
                child.Measure(availableSize);

                if (Orientation == Orientation.Vertical)
                {
                    desiredSize.Width = Math.Max(desiredSize.Width,
                    child.DesiredSize.Width);
                    desiredSize.Height += child.DesiredSize.Height;
                }
                else
                {
                    desiredSize.Height = Math.Max(desiredSize.Height,
                    child.DesiredSize.Height);
                    desiredSize.Width += child.DesiredSize.Width;
                }
            }
        }
        return desiredSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        double offset = 0;
        foreach (UIElement child in this.Children)
        {
            if (child != null)
            {
                if (Orientation == Orientation.Vertical)
                {               
                    child.Arrange(new Rect(0, offset, finalSize.Width,
                    child.DesiredSize.Height));                 
                    offset += child.DesiredSize.Height;
                }
                else
                {                   
                    child.Arrange(new Rect(offset, 0, child.DesiredSize.Width,
                    finalSize.Height));
                    offset += child.DesiredSize.Width;
                }
            }
        }
        return finalSize;
    }
}
  • DesiredSize (размер возвращенный MeasureOverride), является суммой размеров детей в направлении StackPanel и размер наибольшего ребенок в другом направлении.

  • RenderSize представляет собой окончательный размер StackPanel после компоновки завершено.

  • ActualHeight точно такой же, как RenderSize.Height.

Чтобы полагаться на эти свойства, вы должны обращаться к ним только в обработчике событий для события LayoutUpdated.

Ответ 2

Выше ответ правильный, за исключением того, что RenderSize и ActualHeight могут иметь временно разные значения. RenderSize устанавливается перед OnRender, тогда как ActualHeight устанавливается после того, как WPF закончил компоновку и обработал обработку этого элемента управления. В самом конце LayoutUpdated получает повышение.

Следовательно, RenderSize может использоваться в OnRender, но у ActualHeight все еще будет старое значение до начала макета.

Последовательность выглядит следующим образом:

MeasureOverride() => sets DesiredSize
ArrangeOverride() => sets RenderSize
OnRender()

WPF может выполнять эту последовательность несколько раз (рекурсия). Как только все будет установлено, выполняется следующее:

ActualHeight = RenderSize.Height

ActualHeight можно получить в любое время (!) после завершения первого макета, за исключением самого процесса компоновки измерения, организации и рендеринга. WPF гарантирует, что любой код будет завершен до начала обработки компоновки.