Динамическое изменение размера открытого Аккордеона - PullRequest
9 голосов
/ 13 мая 2010

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

    <lt:Accordion Name="MyAccordion"
                  SelectionMode="ZeroOrOne"
                  HorizontalAlignment="Stretch">
        <lt:AccordionItem Name="MyAccordionItem"
                          Header="MyAccordion"
                          IsSelected="True"
                          HorizontalContentAlignment="Stretch"
                          VerticalAlignment="Stretch">
            <StackPanel>
                <Button Content="Grow" Click="Grow"/>
                <Button Content="Shrink" Click="Shrink"/>
                <TextBox Name="GrowTextBox"
                         Text="GrowTextBox"
                         Height="400"
                         Background="Green"
                         SizeChanged="GrowTextBox_SizeChanged"/>
            </StackPanel>
        </lt:AccordionItem>
    </lt:Accordion>


    private void Grow(object sender, System.Windows.RoutedEventArgs e)
    {
        GrowTextBox.Height += 100;
    }

    private void Shrink(object sender, System.Windows.RoutedEventArgs e)
    {
        GrowTextBox.Height -= 100;
    }

    private void GrowTextBox_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
    {
        MyAccordion.UpdateLayout();
        MyAccordionItem.UpdateLayout();
    }

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

Я слабо попытался исправить это, добавив обработчик события SizeChanged, который вызывает UpdateLayout () для Accordion и AccordionItem, но это не имеет никакого визуального эффекта. Я не могу понять, где происходит правильное изменение размера внутри элемента управления Accordion. У кого-нибудь есть идея?

Ответы [ 3 ]

1 голос
/ 05 июля 2011

Попробуйте это

 //here i am creating a size object depending on child items height and width
        // and 25 for accordian item header...
        // if it works you can easily update the following code to avoid exceptional behaviour
        Size size = new Size();
        size.Width = GrowTextBox.ActualWidth;
        size.Height = grow.ActualHeight + shrink.ActualHeight + GrowTextBox.ActualHeight + 25;
        MyAccordion.Arrange(new Rect(size));

В приведенном выше коде я просто переставляю аккордеон в зависимости от размера дочернего элемента.

1 голос
/ 29 апреля 2013

У меня была немного другая проблема - изменение размера моего окна иногда неправильно корректировало размер элемента Accordion, поэтому заголовок следующего элемента застревал под окном или в середине.

Я решил эту проблему, создав таймер, который запускается в SizeChanged и отменяет выбор и сразу же повторно выбирает текущий элемент, после чего макет кажется перенастроенным и корректным.Может помочь и тебе.Вы можете обойтись без таймера, я ввел его для предотвращения непрерывных вызовов, когда пользователь перетаскивает размер окна, он также дает некоторый пернатый эффект из-за задержки.

public partial class MyAccordion : System.Windows.Controls.Accordion
{
    private Timer _layoutUpdateTimer = new Timer(100);

    public MyAccordion
    {
        this.SizeChanged += (s, e) =>
        {
            _layoutUpdateTimer.Stop(); // prevents continuous calls
            _layoutUpdateTimer.Start();
        };
        _layoutUpdateTimer.Elapsed += (s, e) => ReselectItem();
    }

    private void ReselectItem()
    {
        Application.Current.Dispatcher.BeginInvoke((Action)(() =>
        {
            // backup values
            int selectedIndex = this.SelectedIndex;
            AccordionSelectionMode mode = this.SelectionMode;

            // deselect
            this.SelectionMode = AccordionSelectionMode.ZeroOrOne; // allow null selection
            this.SelectedItem = null;

            // restore values (reselect)
            this.SelectionMode = mode;
            this.SelectedIndex = selectedIndex;
        }));
        _layoutUpdateTimer.Stop();
    }
}
1 голос
/ 13 мая 2010

У меня похожая проблема, мой простой взлом выглядит следующим образом:

private void GrowTextBox_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
{
        MyAccordionItem.Measure(new Size());
        MyAccordionItem.UpdateLayout();
}

Надеюсь, у вас это тоже получится ..

Приветствия

...