2012-09-03 16 views
9

Desidero che la finestra rispetti le specifiche MinWidth/MinHeight e MaxWidth/MaxHeight del controllo contenuto all'interno.Vincoli di ridimensionamento della finestra per contenuto

Alcuni suggeriscono di utilizzare SizeToContent, ma questo aiuta solo a impostare la dimensione della finestra iniziale, non i vincoli.

Altri hanno suggerito di ignorare lo MeasureOverride e l'altezza e la larghezza di questa finestra, ma questo sembra essere un po 'impuro, considerando che un problema così insignificante dovrebbe sicuramente avere una soluzione puramente dichiarativa.

solo per citare un'altra soluzione che sembra ragionevole, ma non lavoro (ed era stato già citato in una risposta che ha ottenuto cancellato): legame MinWidth della finestra per MinWidth del controllo non tiene decorazioni delle finestre conto.

risposta

7

Se la dimensione della finestra iniziale è impostata in modo che la dimensione del contenuto effettivo non venga forzata da MinWidth/MinHeight e MaxWidth/MaxHeight del contenuto nella passata di layout iniziale (ad esempio, utilizzando Window.SizeToContent = "WidthAndHeight"), quindi equazioni seguenti sono vere:

Window.ActualSize - Content.ActualSize = 
     Window.MinSize - Content.MinSize = Window.MaxSize - Content.MaxSize. 

sulla base di queste equazioni è possibile derivare il seguente codice:

public MainWindow() 
{ 
    InitializeComponent(); 

    this.SizeChanged += OnWindowSizeChanged; 
} 

private static void OnWindowSizeChanged(object sender, SizeChangedEventArgs e) 
{ 
    var window = (Window)sender; 
    var content = (FrameworkElement)window.Content; 

    window.MinWidth = window.ActualWidth - content.ActualWidth + content.MinWidth; 
    window.MaxWidth = window.ActualWidth - content.ActualWidth + content.MaxWidth; 

    window.MinHeight = window.ActualHeight - content.ActualHeight + content.MinHeight; 
    window.MaxHeight = window.ActualHeight - content.ActualHeight + content.MaxHeight; 

    window.SizeChanged -= OnWindowSizeChanged; 
} 

non so come raggiungere questo obiettivo in modo efficiente utilizzando l'approccio dichiarativo pura dal momento che il codice deve essere eseguito solo una volta dopo l'ini passaggio del layout di prova.

+0

Sapete se SizeChanged verrà attivato nel caso in cui MinWidth/MinHeight o MaxWidth/MaxHeight of Content cambino? O dovrei associare un legame a queste proprietà separatamente? – EFraim

+0

Questo è sicuramente utile, attualmente sto verificando se risolve interamente il mio problema. – EFraim

1

Utilizzare l'estensione del markup Binding. Un'associazione è il modo di dire di wpf quando questa proprietà (fonte) cambia aggiornare qualche altra proprietà (obiettivo). In questo caso la proprietà MinWidth della griglia è l'origine e la proprietà MinWidth della finestra è l'obiettivo.

<Window x:Class="MinMaxValuesOnWindows.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="600" Width="800" 
    MinWidth="{Binding ElementName=gridy, Path=MinWidth}" 
    MinHeight="{Binding ElementName=gridy, Path=MinHeight}" 
    MaxWidth="{Binding ElementName=gridy, Path=MaxWidth}" 
    MaxHeight="{Binding ElementName=gridy, Path=MaxHeight}"> 
    <Grid Name="gridy" MinHeight="80" MinWidth="80" MaxHeight="300" MaxWidth="300"/> 
</Window> 

Come lei ha ricordato nel argomento questo non del tutto funziona, ma è possibile utilizzare un convertitore sul legame di aggiungere altezza e la larghezza del telaio della finestra prima di aggiornare l'obiettivo vincolante (potrebbe richiedere un PInvoke). Poiché dubito che lo spessore della cornice della finestra stia cambiando dinamicamente nell'applicazione, probabilmente questo può essere solo un valore costante (non necessariamente vero se l'utente cambia i temi).

+0

Quello che dici è tecnicamente vero, ma come ho notato nella domanda la difficoltà principale che devo affrontare è capire le dimensioni della decorazione in modo indipendente dal tema. L'altra risposta risolve questa parte del puzzle, quindi lo accetterò. – EFraim

5

Alcuni suggeriscono di utilizzare SizeToContent, ma questo aiuta solo a impostare la dimensione della finestra iniziale, non i vincoli.

ho lavorato intorno a questo impostando i MinWidth e MinHeight proprietà subito dopo finestre era inizializzati:

MainWindow.xaml

<Window ... SizeToContent="WidthAndHeight"> 
    ... 
</Window> 

MainWindow.xaml.cs

public MainWindow() 
{ 
    InitializeComponent(); 
    SourceInitialized += (s, e) => 
    { 
     MinWidth = ActualWidth; 
     MinHeight = ActualHeight; 
    }; 
} 
+0

Questa dovrebbe essere la risposta accettata. – user2481095

Problemi correlati