Панель стека: высота по сравнению с фактической высотой по сравнению с экстентной высотой по сравнению с ViewportHeight против желаемого размера против RenderSize - PullRequest
23 голосов
/ 19 июня 2011

я хочу знать высоту всех предметов моего StackPanel.

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

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

Из MSDN:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

элементы, чтобы убедиться, что они помещаются в StackPanel .

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

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

Ответы [ 2 ]

14 голосов
/ 19 июня 2011

Как вы знаете, 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 .

3 голосов
/ 11 февраля 2014

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

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

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

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

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

ActualHeight = RenderSize.Height

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

...