Alinhar itens em um painel de pilha?

148

Eu queria saber se posso ter 2 controles em um StackPanel orientado para horizontal, para que o item certo seja encaixado no lado direito do StackPanel.

Eu tentei o seguinte, mas não funcionou:

<StackPanel Orientation="Horizontal">
    <TextBlock>Left</TextBlock>
    <Button Width="30" HorizontalAlignment="Right">Right<Button>
</StackPanel>

No trecho de código acima, quero que o botão seja encaixado no lado direito do StackPanel.

Nota: Eu preciso que isso seja feito com o StackPanel, não com o Grid etc.

Shimmy Weitzhandler
fonte
Você menciona explicitamente nenhuma grade, mas foi exatamente assim que consegui isso. Ficarei interessado em saber se alguém tem uma resposta que não seja da grade para sua pergunta que atenda às minhas próprias necessidades.
JMD
Sim, alguém me deu um projeto cheio de painéis de pilha dessa maneira, é assim que ele quer que seja corrigido.
Shimmy Weitzhandler
3
Eu sei que é (extremamente) tarde, mas você não poderia colocar um dockpanel dentro do stackpanel?
Kian
1
@ Kian, você está absolutamente certo com o seu comentário, pensei nele, tentei e funcionou perfeitamente.
Gabrielius

Respostas:

221

Você pode conseguir isso com um DockPanel:

<DockPanel Width="300">
    <TextBlock>Left</TextBlock>
    <Button HorizontalAlignment="Right">Right</Button>
</DockPanel>

A diferença é que a StackPanelorganizará elementos filho em uma única linha (vertical ou horizontal) enquanto a DockPaneldefine uma área na qual você pode organizar elementos filho horizontal ou verticalmente, um em relação ao outro (a Dockpropriedade altera a posição de um elemento em relação a outro elementos do mesmo contêiner.As propriedades de alinhamento, como, por exemplo HorizontalAlignment, alteram a posição de um elemento em relação ao elemento pai).

Atualizar

Como apontado nos comentários, você também pode usar a FlowDirectionpropriedade de a StackPanel. Veja a resposta de @ D_Bester .

Dirk Vollmar
fonte
1
isto é o que eu quis dizer com o 'etc.' Eu acho que a resposta é não, e terá que fazê-lo da maneira mais difícil, leia o meu comentário para JMD acima #
Shimmy Weitzhandler
Bem, o StackPanel simplesmente não pode fazer o layout que você deseja. Um Grid lhe dará mais flexibilidade, mas uma mudança do StackPanel para o DockPanel não parece muito difícil.
Dirk Vollmar
2
Não há DockPanel no Windows 8, existem outras soluções?
Christoph
@DirkVollmar Na verdade, o StackPanel funciona muito bem, veja minha resposta.
D_Bester
1
Se você quer deixar alinhar o item mais à direita, conjunto LastChildFill="False"que é <DockPanel LastChildFill="False">, veja stackoverflow.com/a/9599290/4573839
Yang Yu Jian
68

Yo pode definir FlowDirectionde Stack panelque RightToLeft, em seguida, todos os itens serão alinhados para o lado direito.

RusBog
fonte
3
Observe, no entanto, que isso altera (inverte) a ordem dos controles no StackPanel.
precisa saber é o seguinte
1
@ slattery Se FlowDirection for um problema, basta colocar em outro StackPanel e especificar o FlowDirection. Veja minha resposta.
D_Bester
1
@ rumblefx0: observe, o DockPanel também reverte a ordem dos controles, se estiverem encaixados à direita ou na parte inferior. Isso ocorre porque o primeiro controle é encaixado primeiro.
Olivier Jacot-Descombes
29

Para aqueles que tropeçar em cima desta questão, aqui é a forma de alcançar esse layout com um Grid:

<Grid>
    <TextBlock Text="Server:"/>
    <TextBlock Text="http://127.0.0.1" HorizontalAlignment="Right"/>
</Grid>

cria

Server:                                                                   http://127.0.0.1
despenteado
fonte
18

Não foi possível obter esse trabalho usando um DockPanel da maneira que eu queria e inverter a direção do fluxo de um StackPanel é problemático. Usar uma grade não é uma opção, pois os itens nela podem estar ocultos em tempo de execução e, portanto, não sei o número total de colunas em tempo de design. A melhor e mais simples solução que eu poderia encontrar é:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <StackPanel Grid.Column="1" Orientation="Horizontal">
        <!-- Right aligned controls go here -->
    </StackPanel>
</Grid>

Isso fará com que os controles dentro do StackPanel sejam alinhados ao lado direito do espaço disponível, independentemente do número de controles - tanto no design quanto no tempo de execução. Yay! :)

Ross
fonte
Se FlowDirection for um problema, basta colocar em outro StackPanel e especificar o FlowDirection. Veja minha resposta.
D_Bester
Penso que esta é uma solução mais limpa muito mais do que mexer com direções de fluxo aninhados
Ross
5

Isso funciona perfeitamente para mim. Basta colocar o botão primeiro, pois você está começando à direita. Se o FlowDirection se tornar um problema, adicione um StackPanel ao seu redor e especifique FlowDirection = "LeftToRight" para essa parte. Ou simplesmente especifique FlowDirection = "LeftToRight" para o controle relevante.

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" FlowDirection="RightToLeft">
    <Button Width="40" HorizontalAlignment="Right" Margin="3">Right</Button>
    <TextBlock Margin="5">Left</TextBlock>
    <StackPanel FlowDirection="LeftToRight">
        <my:DatePicker Height="24" Name="DatePicker1" Width="113" xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit" />    
    </StackPanel>
    <my:DatePicker FlowDirection="LeftToRight" Height="24" Name="DatePicker1" Width="113" xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit" />    
</StackPanel>
D_Bester
fonte
4
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <TextBlock Text="Left"  />
    <Button Width="30" Grid.Column="1" >Right</Button>
</Grid>
Attif
fonte
0

para Windows 10, use o relatedPanel em vez do painel de pilha e use

relativepanel.alignrightwithpanel = "true"

para os elementos contidos.

Ahmed.Net
fonte
0

Se você estiver tendo um problema como o que eu tinha, onde as etiquetas estavam centralizadas no meu painel de pilha vertical, certifique-se de usar controles de largura total. Exclua a propriedade Width ou coloque seu botão em um contêiner de largura total que permita o alinhamento interno. O WPF é sobre o uso de contêineres para controlar o layout.

<StackPanel Orientation="Vertical">
    <TextBlock>Left</TextBlock>
    <DockPanel>
        <Button HorizontalAlignment="Right">Right</Button>
    </DockPanel>
</StackPanel>

StackPanel vertical com etiqueta esquerda seguida de botão direito

Eu espero que isso ajude.

Christopher Zahrobsky
fonte
-8

Talvez não seja o que você deseja se precisar evitar valores de tamanho codificados, mas às vezes eu uso um "calço" (Separador) para isso:

<Separator Width="42"></Separator>
B. Clay Shannon
fonte