HorizontalAlignment = Allunga, Larghezza massima e Sinistra allineati contemporaneamente?
Domanda
Sembra che dovrebbe essere facile ma sono sconcertato. In WPF, vorrei una TextBox che si estende fino alla larghezza del suo genitore, ma solo alla larghezza massima. Il problema è che voglio che sia lasciato giustificato all'interno del suo genitore. Per farlo allungare devi usare HorizontalAlignment = " Stretch " ;, ma il risultato è centrato. Ho sperimentato con HorizontalContentAlignment, ma non sembra fare nulla.
Come faccio a far crescere questa casella di testo blu con le dimensioni della finestra, avere una larghezza massima di 200 pixel e essere giustificata?
<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 è il trucco?
Soluzione
Puoi impostare HorizontalAlignment
su Sinistra, impostare MaxWidth
e quindi associare Width
a ActualWidth
del elemento padre:
<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>
Altri suggerimenti
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MaxWidth="200"/>
</Grid.ColumnDefinitions>
<TextBox Background="Azure" Text="Hello" />
</Grid>
Entrambe le risposte fornite hanno funzionato per il problema che ho dichiarato - Grazie!
Nella mia vera applicazione, però, stavo cercando di vincolare un pannello all'interno di ScrollViewer e il metodo di Kent non ha funzionato molto bene per qualche motivo che non mi sono preoccupato di rintracciare. Fondamentalmente i controlli potrebbero espandersi oltre l'impostazione MaxWidth e sconfiggere il mio intento.
La tecnica di Nir ha funzionato bene e non ha avuto problemi con ScrollViewer, anche se c'è una cosa minore a cui fare attenzione. Vuoi essere sicuro che i margini destro e sinistro in TextBox siano impostati su 0 o si metteranno di mezzo. Ho anche modificato l'associazione per utilizzare ViewportWidth anziché ActualWidth per evitare problemi quando è stata visualizzata la barra di scorrimento verticale.
Puoi usarlo per la larghezza del tuo DataTemplate:
Width="{Binding ActualWidth,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}"
Assicurati che la tua radice DataTemplate abbia Margin = " 0 " (puoi usare alcuni pannelli come root e impostare il Margine sui figli di quella radice)
Forse posso ancora aiutare qualcuno a rispondere a questa domanda, perché si tratta di un problema molto vecchio.
Avevo bisogno anche di questo e ho scritto un comportamento per occuparmene. Quindi ecco il 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;
}
}
}
}
Quindi puoi usarlo in questo modo:
<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 infine dimenticare di utilizzare lo spazio dei nomi System.Windows.Interactivity
per utilizzare il comportamento.
Vorrei usare 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>