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.

Foi útil?

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:

Captura de tela

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top