我有一个Accordion,其内容的高度可以动态调整大小。我想看到Accordion动态响应子项的高度,但我在这方面遇到了麻烦。
<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();
}
请注意,如果我塌陷然后重新打开手风琴,它就会按照我想要的方式成型,但我希望在孩子调整大小时立即调整大小。
我试图通过添加一个在Accordion和AccordionItem上调用UpdateLayout()的SizeChanged事件处理程序来解决这个问题,但这没有任何视觉效果。我无法弄清楚在Accordion控件内进行适当调整的位置。有没有人有想法?
答案 0 :(得分:1)
我有类似的问题,我的简单黑客如下:
private void GrowTextBox_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
{
MyAccordionItem.Measure(new Size());
MyAccordionItem.UpdateLayout();
}
希望它也适合你..
干杯
答案 1 :(得分:1)
试试这个
//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));
在上面的代码中,我只是根据子项目大小重新排列手风琴。
答案 2 :(得分:1)
我遇到了一个稍微不同的问题 - 调整窗口大小有时无法正确调整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();
}
}