我想只允许我的WPF窗口水平调整大小。 我怎样才能做到最好?
答案 0 :(得分:29)
如果您想使用MinHeight
和MaxHeight
方法,但仍允许窗口自动调整大小以适合其内容的大小:
<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">
在代码隐藏中:
private void window_Loaded(object sender, RoutedEventArgs e)
{
this.MinWidth = this.ActualWidth;
this.MinHeight = this.ActualHeight;
this.MaxHeight = this.ActualHeight;
}
答案 1 :(得分:26)
如果您将窗口的MinHeight
和MaxHeight
属性设置为所需的高度,则窗口将具有固定的高度
答案 2 :(得分:3)
这是一种痛苦。基本上你需要设置一个钩子函数来处理windows消息。然后,您将捕获WM_SIZING(0x0214)消息并修改参数,以便无法更改水平维度。
Pete Brown在他的博客上也有关于这个主题的一些很好的信息。
答案 3 :(得分:1)
您可以尝试数据绑定到窗口的大小,然后在更改垂直尺寸时将大小设置回旧值。
答案 4 :(得分:1)
以下解决方案允许您保持SizeToContent
完整,
在您的窗口中不需要Win32 Interop
或代码:
它确实依赖于Reactive Extensions
在Package Manager
运行中:
Install-Package System.Reactive
然后,您首先要创建一个新的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;
});
}
}
然后在窗口底部添加UIElement
并应用Behavior
:
<Border Background="Gray"
Height="10"
Cursor="SizeNS"
Grid.ColumnSpan="2">
<i:Interaction.Behaviors>
<b:VerticalResizeWindowBehavior MinHeight="600"/>
</i:Interaction.Behaviors>
</Border>
在您的窗口上设置以下属性:
ResizeMode="NoResize"
SizeToContent="Width"
注意:在此示例中,允许用户调整Vertically
但不调整Horizontally
的尺寸。
您可以轻松更改代码以允许相反,或添加属性
使其可配置。
答案 5 :(得分:0)
如果您想使用MinHeight和MaxHeight方法,但仍允许窗口自动调整大小以适合其内容的大小:
要允许自动调整内容大小,请不要使用Loaded事件。改为使用ContentRendered事件。
答案 6 :(得分:0)
如果您有以下要求: *宽度可以由用户调整大小(ResizeMode = CanResize) *高度自动调整大小(SizeToContent = Height)
它不会有两个原因: *没有ResizeMode = CanResizeHeight *当用户调整窗口大小时,它会将SizeToContent打包为“手动”
我使用的一个简单的黑客就是不断强制“SizeToContent”恢复到我想要的值。
<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;
}
您还可以使用ContentRendered事件。 PropertyChanged事件无效。这并不完美,因为用户仍然可以垂直移动光标,如果快速完成,会导致一些闪烁。
答案 7 :(得分:0)
基于User3810621和其他用户的回答,可以将其转变为可重用的行为,该行为将在第一个内容呈现后将计算出的大小锁定为min和/或max:
namespace whatever.util.wpf.behaviors
{
using System.Windows;
using System.Windows.Interactivity;
public class LockInitialSize : Behavior<Window>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.ContentRendered += OnContentRendered;
}
protected override void OnDetaching()
{
// possibly detached before ever rendering
AssociatedObject.ContentRendered -= OnContentRendered;
base.OnDetaching();
}
private void OnContentRendered(object s, EventArgs e)
{
// Just once
AssociatedObject.ContentRendered -= OnContentRendered;
if (MinWidth)
{
AssociatedObject.MinWidth = AssociatedObject.ActualWidth;
}
/// ... MaxWidth, MinHeight, MaxHeight
}
#region MinWidth Property
public bool MinWidth
{
get => (bool)GetValue(MinWidthProperty);
set => SetValue(MinWidthProperty, value);
}
public static readonly DependencyProperty MinWidthProperty =
DependencyProperty.Register(nameof(MinWidth), typeof(bool), typeof(LockInitialSize));
#endregion
// ... MaxWidth, MinHeight, MaxHeight
}
}
其余的重复值很小,为简洁起见,省略了它们。
用法:
<Window ...
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:whatever.util.wpf.behaviors;assembly=whatever"
SizeToContent="Height"
...>
<i:Interaction.Behaviors>
<behaviors:LockInitialSize MinHeight="True" MaxHeight="True" />
</i:Interaction.Behaviors>