Desidero consentire la ridimensionamento orizzontale della finestra WPF. Come posso raggiungere questo obiettivo?Finestra WPF: consente solo il ridimensionamento orizzontale
risposta
Se si impostano le MinHeight
e MaxHeight
attributi della finestra fino all'altezza desiderata della finestra avrà un'altezza fissa
Funziona a meraviglia ... così ovvio quando ci pensi. Grazie –
Purtroppo incompatibile con il calcolo automatico dell'altezza in base alla dimensione del contenuto. –
È 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.
È 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.
L'unico inconveniente è che è la gestione postale. – Amsakanna
Vero. Ma nella maggior parte dei casi ho il sospetto che sarà abbastanza veloce che l'utente non se ne accorge. –
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;
}
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'. –
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.
Potresti incollare la fonte di questa citazione? – Tomasito
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.
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.
Wow, pensavo che l'impostazione di MinHeight, Height e MaxHeight sullo stesso valore funzionasse, ma non è così. Bello sapere. – DHN