HorizontalAlignment = Allunga, Larghezza massima e Sinistra allineati contemporaneamente?

StackOverflow https://stackoverflow.com/questions/280331

  •  07-07-2019
  •  | 
  •  

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?

È stato utile?

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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top