largura de constranger StackPanel para o menor elemento filho
-
22-08-2019 - |
Pergunta
Como posso restringir a largura de uma WPF de StackPanel
vertical para o item mais estreita que ele contém. A largura do StackPanel
não deve ser maior do que a largura de qualquer outro elemento filho.
Solução
Infelizmente, a IValueConverter abordagem nem sempre trabalho; se as crianças são adicionados à StackPanel estaticamente, por exemplo, a coleção de criança estará vazia no momento da ligação (por isso eu descobri). A solução mais simples é criar um painel personalizado:
public class ConstrainedStackPanel : StackPanel
{
public ConstrainedStackPanel()
{
}
protected override Size MeasureOverride(Size constraint)
{
foreach (var item in this.Children)
{
// FrameworkElement has the Width property we care about.
FrameworkElement element = item as FrameworkElement;
if (element != null)
constraint.Width = Math.Min(element.Width, constraint.Width);
}
return base.MeasureOverride(constraint);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
foreach (var item in this.Children)
{
// FrameworkElement has the Width property we care about.
FrameworkElement element = item as FrameworkElement;
if (element != null)
arrangeSize.Width = Math.Min(element.Width, arrangeSize.Width);
}
return base.ArrangeOverride(arrangeSize);
}
}
Você pode usar o painel como ilustrado pelo seguinte XAML:
<StackPanel Margin="5">
<TextBlock Text="StackPanel:" FontWeight="Bold" />
<StackPanel x:Name="panelA">
<Button Width="100" Content="100" />
<Button Width="200" Content="200" />
<Button Width="300" Content="300" />
<Button Width="400" Content="400" />
</StackPanel>
<TextBlock Text="ConstrainedStackPanel:" FontWeight="Bold" Margin="0,10,0,0" />
<l:ConstrainedStackPanel x:Name="panelB">
<Button Width="100" Content="100" />
<Button Width="200" Content="200" />
<Button Width="300" Content="300" />
<Button Width="400" Content="400" />
</l:ConstrainedStackPanel>
</StackPanel>
O que irá tornar algo como o seguinte:
Espero que isso ajude.
Outras dicas
Eu tentei ligação à propriedade ActualWidth, até mesmo criar um conversor para compensar o valor, e isso funciona muito bem com uma exceção: como você expandir o tamanho do recipiente, a largura é atualizado corretamente, mas quando para fazer o recipiente menor, a largura do conteúdo real fica menor, mas a "largura da página" de quaisquer scrollviewers não. eu tenho certeza que há uma maneira de contornar isso, mas eu não tê-lo encontrado.
Você não pode. A StackPanel
orientado verticalmente sempre alocar o máximo de largura que solicitar seus filhos.
Você seria melhor fora escrevendo um painel personalizado para atingir o seu comportamento desejado.