Я хочу только разрешить изменение размера окна WPF по горизонтали. Как я могу это достичь?
Окно WPF - разрешает только горизонтальное изменение размера
Ответ 1
Если вы установите атрибуты MinHeight
и MaxHeight
окна на нужную высоту, окно будет иметь фиксированную высоту
Ответ 2
Если вы хотите использовать подход 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;
}
Ответ 3
Это какая-то боль. В основном вам нужно настроить функцию hook для обработки сообщений Windows. Затем вы поймаете сообщение WM_SIZING (0x0214) и измените параметры, чтобы изменить горизонтальное измерение.
Пит Браун также имеет отличную информацию по этой теме в своем блоге.
Ответ 4
Вы можете попробовать привязать данные к размеру окна, а затем установить размер обратно на прежнее значение всякий раз, когда изменяется размер по вертикали.
Ответ 5
Следующее решение позволяет оставить SizeToContent
неповрежденным,
не требует Win32 Interop
или кода в вашем окне:
Он полагается на Реактивные расширения
В Package Manager
run:
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
Вы можете легко изменить код, чтобы разрешить противоположное, или добавить свойства
чтобы сделать его настраиваемым.
Ответ 6
Если вы хотите использовать подход MinHeight и MaxHeight, но все же разрешите автоматическому размеру окна, чтобы он соответствовал размеру его содержимого:
Чтобы разрешить автоматическое определение содержимого, не используйте событие Loaded. Вместо этого используйте событие ContentRendered.
Ответ 7
Если у вас есть следующие требования: * Ширина может быть изменена пользователем (ResizeMode = CanResize) * Высота автоматически зависит от размера (SizeToContent = Height)
Он не будет работать по двум причинам: * Нет ResizeMode = CanResizeHeight * когда пользователь изменяет размер окна, он будет clobber SizeToContent до "Manual"
Простой хак, который я использую, заключается в том, чтобы постоянно принудительно "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 не будет работать. Это не идеально, так как пользователь может перемещать курсор по вертикали, и это приведет к некоторому мерцанию, если оно будет выполнено быстро.