2010-06-23 20 views

risposta

22

Se si impostano le MinHeight e MaxHeight attributi della finestra fino all'altezza desiderata della finestra avrà un'altezza fissa

+0

Funziona a meraviglia ... così ovvio quando ci pensi. Grazie –

+9

Purtroppo incompatibile con il calcolo automatico dell'altezza in base alla dimensione del contenuto. –

3

È una specie di dolore. Fondamentalmente è necessario impostare una funzione di hook per elaborare i messaggi di Windows. Quindi si cattura il messaggio WM_SIZING (0x0214) e si modificano i parametri in modo che la dimensione orizzontale non possa essere modificata.

Pete Brown ha anche alcune fantastiche informazioni su questo argomento sul suo blog.

1

È possibile provare l'associazione dei dati alle dimensioni della finestra e quindi impostare la dimensione sul vecchio valore ogni volta che viene modificata la dimensione verticale.

+0

L'unico inconveniente è che è la gestione postale. – Amsakanna

+0

Vero. Ma nella maggior parte dei casi ho il sospetto che sarà abbastanza veloce che l'utente non se ne accorge. –

26

Se si desidera utilizzare l'approccio MinHeight e MaxHeight ma consentono ancora la finestra di dimensioni automaticamente per adattare le dimensioni del suo contenuto:

<Window x:Class="MyWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     SizeToContent="WidthAndHeight" 
     ResizeMode="CanResize" 
     Loaded="window_Loaded"> 

Nel code-behind:

private void window_Loaded(object sender, RoutedEventArgs e) 
{ 
    this.MinWidth = this.ActualWidth; 
    this.MinHeight = this.ActualHeight; 
    this.MaxHeight = this.ActualHeight; 
} 
+0

Proprio come Tim Richards consiglia, ho dovuto spostare le proprietà 'MinHeight' e' MaxHeight' sull'evento 'ContentRendered' dopo aver notato il bordo inferiore di un' TextBox' e 'Button' venivano ritagliati in una' Grid' contenuta all'interno di un 'GroupBox'. –

0

Se si desidera utilizzare l'approccio MinHeight e MaxHeight ma consentire comunque alla finestra di ridimensionarsi automaticamente per adattarsi alle dimensioni del suo contenuto:

Per consentire il ridimensionamento automatico del contenuto non utilizzare l'evento Loaded. Utilizzare invece l'evento ContentRendered.

+0

Potresti incollare la fonte di questa citazione? – Tomasito

0

Se si dispone dei seguenti requisiti: * Larghezza può essere ridimensionata utente (ResizeMode = CanResize) * Altezza è dimensionato automaticamente (SizeToContent = altezza)

Non funzionerà per due motivi: * lì c'è ResizeMode = CanResizeHeight * quando l'utente ridimensiona la finestra, si clobber SizeToContent su "Manuale"

Un semplice trucco che uso è quello di forzare costantemente "SizeToContent" di nuovo al mio valore desiderato.

<Window x:Class="MyWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    SizeToContent="Height" 
    ResizeMode="CanResize" 
    LayoutUpdated="LayoutUpdated"> 

private void LayoutUpdated(object sender, EventArgs e) 
{ 
    SizeToContent = SizeToContent.Height; 
} 

È inoltre possibile utilizzare l'evento ContentRendered. L'evento PropertyChanged non funzionerà. Questo non è perfetto, dal momento che l'utente può ancora spostare il cursore verticalmente, e provocherà un po 'di sfarfallio se fatto rapidamente.

1

La seguente soluzione consente di lasciare intatto SizeToContent,
non richiede Win32 Interop o codice dietro nella finestra:

lo fa affidamento su Reactive Extensions

Nella Package Manager corsa:

Install-Package System.Reactive 

Quindi si inizia creando un nuovo Behavior:

public class VerticalResizeWindowBehavior : Behavior<UIElement> 
{ 
    public static readonly DependencyProperty MinHeightProperty = DependencyProperty.Register("MinHeight", typeof(double), typeof(VerticalResizeWindowBehavior), new PropertyMetadata(600.0)); 
    public double MinHeight 
    { 
     get { return (double)GetValue(MinHeightProperty); } 
     set { SetValue(MinHeightProperty, value); } 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     var window = Window.GetWindow(AssociatedObject); 
     var mouseDown = Observable.FromEventPattern<MouseButtonEventArgs>(AssociatedObject, "MouseLeftButtonDown") 
            .Select(e => e.EventArgs.GetPosition(AssociatedObject)); 

     var mouseUp = Observable.FromEventPattern<MouseButtonEventArgs>(AssociatedObject, "MouseLeftButtonUp") 
           .Select(e => e.EventArgs.GetPosition(AssociatedObject)); 

     var mouseMove = Observable.FromEventPattern<MouseEventArgs>(AssociatedObject, "MouseMove") 
            .Select(e => e.EventArgs.GetPosition(AssociatedObject)); 

     var q = from start in mouseDown 
       from position in mouseMove.TakeUntil(mouseUp) 
       select new { X = position.X - start.X, Y = position.Y - start.Y }; 

     mouseDown.Subscribe(v => AssociatedObject.CaptureMouse()); 
     mouseUp.Subscribe(v => AssociatedObject.ReleaseMouseCapture()); 

     q.ObserveOnDispatcher().Subscribe(v => 
     { 
      var newHeight = window.Height + v.Y; 
      window.Height = newHeight < MinHeight ? MinHeight : newHeight;     
     }); 
    } 
} 

quindi si aggiunge un UIElement alla parte inferiore della finestra e applicare le Behavior:

<Border Background="Gray" 
     Height="10" 
     Cursor="SizeNS" 
     Grid.ColumnSpan="2"> 
    <i:Interaction.Behaviors> 
     <b:VerticalResizeWindowBehavior MinHeight="600"/> 
    </i:Interaction.Behaviors> 
</Border> 

impostare le seguenti proprietà sulla vostra finestra:

ResizeMode="NoResize" 
SizeToContent="Width" 

Nota: In questo esempio , l'utente può ridimensionare Vertically ma non Horizontally
È possibile modificare facilmente il codice per consentire l'opp osite o aggiungi le proprietà
per renderlo configurabile.

Problemi correlati