WPF Layout - Geting uma coluna para preencher o espaço disponível
-
12-09-2019 - |
Pergunta
Eu tenho um ListBox
que tem uma grade em seu modelo para permitir 4 colunas. Uma coluna é o texto real do ListBox
. Eu quero essa coluna para preencher o espaço horizontal disponível.
As definições de coluna são:
<ControlTemplate TargetType="ListBoxItem">
<Grid ScrollViewer.CanContentScroll="True" Margin="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<CheckBox VerticalAlignment="Center" Grid.Column="0" IsChecked="{Binding IsSelected,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay}" />
<TextBlock VerticalAlignment="Center" Grid.Column="1" Margin="5,0,5,0" Text="{Binding Id}" />
<TextBlock VerticalAlignment="Center" Grid.Column="2" Margin="5,0,5,0" Text="{Binding Title}" />
<Button HorizontalAlignment="Right" Grid.Column="3" Tag="{Binding Id}" Margin="5,0,5,0">-></Button>
</Grid>
</ControlTemplate>
Eu tentei várias permutações deste e nada vai obtê-lo a correção na janela, exceto por uma configuração de tamanho explícito. Então, quando eu redimensionar a janela não redimensionar com ele.
O ListBox
é envolto em um ScrollViewer
para permitir a rolagem vertical (eu estou supondo que é o que está me atrapalhando.)
Algumas ideias sobre como obter a terceira coluna para preencher apenas o espaço disponível e não mais?
Solução 4
Eu finalmente descobrir isso.
A caixa de listagem contendo necessária para definir a barra de rolagem horizontal para pessoas com deficiência como esta:
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Uma vez eu fiz que a grade dimensionada perfeitamente.
Um dia desses eu vou descobrir como todos essa "coisa declarativa" obras.
Outras dicas
Você precisa os comportamentos de ListBox
de controle, ou você está usando-o para a disposição única.
Se você estiver usando-o apenas para layout, você pode trocar o ListBox
para um interior ItemsControl
de um ScrollViewer
.
Este código (massacrado ao trabalho no designer) mostram o seguinte:
<ScrollViewer>
<ItemsControl>
<!--<ListBox>-->
<Grid Margin="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<CheckBox VerticalAlignment="Center" Grid.Column="0" IsChecked="True" />
<TextBlock VerticalAlignment="Center" Grid.Column="1" Margin="5,0,5,0" Text="Id" />
<TextBlock VerticalAlignment="Center" Grid.Column="2" Margin="5,0,5,0" Text="Title" />
<Button HorizontalAlignment="Right" Grid.Column="3" Margin="5,0,5,0">-></Button>
</Grid>
<!--</ListBox>-->
</ItemsControl>
</ScrollViewer>
O ListBox
tem alguma propriedade de matar largura por si as crianças, assim como um TreeView
faz. Então, se você pode evitar usá-lo, por justos motivos de layout, isso pode ser as opções mais rápidas.
Caso contrário, você precisa vincular a largura de vocês Grid
à largura do objeto fictício fora do ListView
, mas o partido confuso é lidar com a mudança largura que as aparece barra de rolagem / desaparece.
Por que você precisa para quebrar a caixa de listagem em um ScrollViewer? A caixa de listagem exibe automaticamente o ScrollViewer quando seu conteúdo não caber no espaço disponível. Você pode removê-lo do XAML e ainda deve funcionar bem. Pelo menos ele fez por mim. :)
Eu tentei o seu ControlTemplate para fora e parecia funcionar muito bem. O problema é que, enquanto a terceira coluna é redimensionada para a largura da caixa de listagem, se o texto na 3ª coluna é muito longa, a 4ª coluna não aparecerá até que todo o texto é visível.
Eu também tentei outro método de layout, que eu não tenho certeza sobre em termos de performance, mas a idéia era usar um DockPanel em vez de um Grid. Eu adicionei a terceira coluna última no XAML para torná-lo preencher o espaço restante, e ancorado-lo para a esquerda (I ancorada a 4ª coluna à direita). Ainda gostaria de exibir a seqüência inteira na 3ª coluna. Eu não sei por que isso está acontecendo, e por isso o texto não vai embrulhar ou use reticências quando o espaço disponível não é suficiente para que o texto de exibição.
<Window.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<DockPanel Width="Auto">
<CheckBox Width="20" VerticalAlignment="Center" DockPanel.Dock="Left" IsChecked="{Binding IsSelected,
RelativeSource={RelativeSource TemplatedParent},
Mode=TwoWay}" />
<TextBlock Width="50" VerticalAlignment="Center" DockPanel.Dock="Left" Margin="5,0,5,0" Text="hi" />
<Button Width="30" HorizontalAlignment="Right" DockPanel.Dock="Right" Margin="5,0,5,0">-></Button>
<TextBlock VerticalAlignment="Center" DockPanel.Dock="Left" Margin="5,0,5,0" Text="afdjfksdhahjklfadshjlasffasdlhjsafdlhjasdfasfhdjlaslfhdjsfdhjlsfdlhjsfdhjsfdddsd" TextTrimming="CharacterEllipsis" TextWrapping="WrapWithOverflow" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Sim, eu sugeriria o espectador de rolagem está mexendo-lo, você poderia vincular a largura da grade para o pai objetos largura real, para que haja um tamanho definido em que o * tem para realmente preencher.