Родитель измеряет размер детей

Я пишу пользовательскую панель, и я хотел бы знать, как сказать своим детям, что, когда им нужно перемерить, их родитель также должен сделать переизмерение.

Например, один из дочерних элементов изменяет свою ширину, и родитель также должен снова измерить, что приводит к тому, что его родитель также выполняет повторное измерение, а затем родитель его родителя и родитель его родителя и так далее. Это похоже на подъем VisualTree. Как я могу это сделать?

Вот код меры панели.. но как сообщить родителю, чтобы он также перемерил

protected override Size MeasureOverride(Size availableSize)
{
 double x;
 double y;
 var children = this.InternalChildren;
 for (int i = 0; i < children.Count; i++)
     {
       UIElement child = children[i];
       child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity);
       y += child.DesiredSize.Height;
       x = Math.Max(x, child.DesiredSize.Width);
      }
 return new Size(x, y);
}

person cyberist    schedule 09.02.2013    source источник
comment
Вы этого не делаете. Это делается WPF автоматически. Просто попробуйте.   -  person Clemens    schedule 10.02.2013
comment
ну, это не происходит автоматически.. если я скажу панели, что у вас есть размер 200 x 200, а затем я изменю ширину дочернего элемента на 300, панель не обновится.. это мое, я задаю этот вопрос   -  person cyberist    schedule 10.02.2013
comment
Вам нужно предоставить больше информации о том, чего вы пытаетесь достичь и почему, и показать код. Люди из Stackoverflow не могут предложить помощь, если мы останемся в догадках.   -  person Benjamin Gale    schedule 10.02.2013
comment
это мой пост .. есть код stackoverflow .com/questions/14775226/   -  person cyberist    schedule 10.02.2013
comment
Если информация та же, вам не следует публиковать еще один вопрос. Если это отличается и требует другого вопроса, пожалуйста, найдите время, чтобы предоставить информацию здесь. Кроме того, вы пробовали предложения, данные для другого вопроса?   -  person Benjamin Gale    schedule 10.02.2013


Ответы (1)


Взгляните на эту очень простую пользовательскую панель, которая размещает дочерние элементы в верхнем левом углу:

public class MyPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        Trace.TraceInformation("MeasureOverride");

        var size = new Size();

        foreach (UIElement element in InternalChildren)
        {
            element.Measure(availableSize);

            size.Width = Math.Max(size.Width, element.DesiredSize.Width);
            size.Height = Math.Max(size.Height, element.DesiredSize.Height);
        }

        return size;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        Trace.TraceInformation("ArrangeOverride");

        foreach (UIElement element in InternalChildren)
        {
            element.Arrange(new Rect(element.DesiredSize));
        }

        return finalSize;
    }
}

Если вы используете его, как показано ниже, с дочерним элементом Button

<local:MyPanel>
    <local:MyPanel>
        <Button Width="100" Height="100" Click="Button_Click"/>
    </local:MyPanel>
</local:MyPanel>

и обработчик Button_Click, который изменяет размер кнопки

private void Button_Click(object sender, RoutedEventArgs e)
{
    ((FrameworkElement)sender).Width += 20;
}

вы заметите, что при каждом нажатии кнопки родительская и родительская панели будут измеряться и располагаться. Вывод трассировки выглядит следующим образом:

CustomPanelTest.vshost.exe Information: 0 : MeasureOverride
CustomPanelTest.vshost.exe Information: 0 : MeasureOverride
CustomPanelTest.vshost.exe Information: 0 : ArrangeOverride
CustomPanelTest.vshost.exe Information: 0 : ArrangeOverride

Следовательно, нет необходимости вызывать Measure или Arrange вручную на родительской панели.

person Clemens    schedule 09.02.2013
comment
Я перехожу к своей панели 200x200, а затем это значение передается дочерним элементам ... но когда я изменяю размер дочернего элемента, панель не обновляется и не измеряется, поэтому я думаю, что это не работает для меня, потому что я использую фиксированные значения размера. что мне нужно сделать, чтобы заставить его работать - person cyberist; 10.02.2013
comment
Вы никогда не должны фиксировать размер панели, если в то же время вы хотите, чтобы она динамически реагировала на изменения размера дочернего элемента. - person Clemens; 10.02.2013
comment
хорошо, что я имею в виду, что я возвращаю 200x200 в качестве размера в MeasureOverride на панели, но затем, как только ширина любого дочернего элемента превышает 200, панель больше не измеряется - person cyberist; 10.02.2013
comment
Возможно, вам следует опубликовать свой код MeasureOverride и ArrangeOverride. - person Clemens; 10.02.2013
comment
Где материал 200x200? И ваш ArrangeOverride тоже был бы интересен. - person Clemens; 10.02.2013
comment
availableSize составляет 200x200.. окно как корневой элемент имеет размер 200x200, откуда еще оно могло взяться, хе-хе - person cyberist; 11.02.2013
comment
Ваш пример кода не показывает, что вы возвращаете availableSize. На самом деле он полностью игнорируется. Возвращать availableSize в любом случае было бы неправильно, так как вы должны вернуть желаемый размер панели (как вы правильно делаете в примере). Так о чем мы здесь говорим? Вы можете снова прочитать документацию по MeasureOverride. чтобы получить изображение. - person Clemens; 11.02.2013