HorizontalAlignment = Stretch, MaxWidth, e alinhados à esquerda, ao mesmo tempo?
Pergunta
Isto parece que deve ser fácil, mas estou perplexo. Em WPF, eu gostaria de uma caixa de texto que se estende até a largura do mesmo pai, mas apenas para uma largura máxima. O problema é que eu quero que ele seja justificado à esquerda dentro de seu pai. Para obtê-lo para esticar você tem que usar HorizontalAlignment = "Stretch", mas, em seguida, o resultado é centrado. Eu experimentei com HorizontalContentAlignment, mas não parece fazer nada.
Como faço para obter esta caixa de texto azul a crescer com o tamanho da janela, tem uma largura máxima de 200 pixels, e ser justificados à esquerda?
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<TextBox Background="Azure" Text="Hello" HorizontalAlignment="Stretch" MaxWidth="200" />
</StackPanel>
</Page>
Qual é o truque?
Solução
Você pode definir HorizontalAlignment
para a esquerda, defina o seu MaxWidth
e Width
em seguida, se ligam à ActualWidth
do elemento pai:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Name="Container">
<TextBox Background="Azure"
Width="{Binding ElementName=Container,Path=ActualWidth}"
Text="Hello" HorizontalAlignment="Left" MaxWidth="200" />
</StackPanel>
</Page>
Outras dicas
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MaxWidth="200"/>
</Grid.ColumnDefinitions>
<TextBox Background="Azure" Text="Hello" />
</Grid>
Ambas as respostas dadas trabalhou para o problema afirmei - Graças
Na minha aplicação real, porém, eu estava tentando restringir um dentro do painel de um ScrollViewer e método de Kent não lidar com isso muito bem por algum motivo eu não me incomodei de rastrear. Basicamente os controles poderia expandir para além da definição MaxWidth e derrotou a minha intenção.
A técnica de Nir trabalhou bem e não tem o problema com o ScrollViewer, embora haja um menor coisa a observar. Você quer ter certeza das margens direita e esquerda na caixa de texto estão definidos para 0 ou eles vão ficar no caminho. Também mudei a ligação usar ViewportWidth vez de ActualWidth para evitar problemas quando a barra de rolagem vertical apareceu.
Você pode usar isso para a largura do seu DataTemplate:
Width="{Binding ActualWidth,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}"
Verifique se o seu DataTemplate raiz tem Margin = "0" (você pode usar algum painel como a raiz e definir a margem para os filhos de que root)
Talvez eu ainda pode ajudar alguém fora que esbarra em esta questão, porque esta é uma questão muito antiga.
Eu precisava deste bem e escreveu um comportamento para cuidar do presente. Então aqui é o comportamento:
public class StretchMaxWidthBehavior : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
base.OnAttached();
((FrameworkElement)this.AssociatedObject.Parent).SizeChanged += this.OnSizeChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
((FrameworkElement)this.AssociatedObject.Parent).SizeChanged -= this.OnSizeChanged;
}
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
this.SetAlignments();
}
private void SetAlignments()
{
var slot = LayoutInformation.GetLayoutSlot(this.AssociatedObject);
var newWidth = slot.Width;
var newHeight = slot.Height;
if (!double.IsInfinity(this.AssociatedObject.MaxWidth))
{
if (this.AssociatedObject.MaxWidth < newWidth)
{
this.AssociatedObject.HorizontalAlignment = HorizontalAlignment.Left;
this.AssociatedObject.Width = this.AssociatedObject.MaxWidth;
}
else
{
this.AssociatedObject.HorizontalAlignment = HorizontalAlignment.Stretch;
this.AssociatedObject.Width = double.NaN;
}
}
if (!double.IsInfinity(this.AssociatedObject.MaxHeight))
{
if (this.AssociatedObject.MaxHeight < newHeight)
{
this.AssociatedObject.VerticalAlignment = VerticalAlignment.Top;
this.AssociatedObject.Height = this.AssociatedObject.MaxHeight;
}
else
{
this.AssociatedObject.VerticalAlignment = VerticalAlignment.Stretch;
this.AssociatedObject.Height = double.NaN;
}
}
}
}
Em seguida, você pode usá-lo assim:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Label" />
<TextBox Grid.Column="1" MaxWidth="600">
<i:Interaction.Behaviors>
<cbh:StretchMaxWidthBehavior/>
</i:Interaction.Behaviors>
</TextBox>
</Grid>
E, finalmente, para se esqueça de usar o namespace System.Windows.Interactivity
usar o comportamento.
Gostaria de usar SharedSizeGroup
<Grid>
<Grid.ColumnDefinition>
<ColumnDefinition SharedSizeGroup="col1"></ColumnDefinition>
<ColumnDefinition SharedSizeGroup="col2"></ColumnDefinition>
</Grid.ColumnDefinition>
<TextBox Background="Azure" Text="Hello" Grid.Column="1" MaxWidth="200" />
</Grid>