[英]WPF borderless window resize with inner-margins
我有一個WPF窗口,在設計器中如下所示:
在內部網格和窗口邊緣之間存在一定的空間,因為在這兩個元素之間繪制了一個DropShadow。
我的問題是無法使用WPF的本機工具調整窗口大小。 如果將ResizeMode設置為CanResize,則句柄是透明的,因此您實際上無法抓住它們。 如果將ResizeMode設置為CanResizeWithGrip,則可以看到該夾點,但是它在整個窗口的右下方。 有什么辦法可以讓我調整大小的手柄顯示內部網格的起始位置,而不是顯示在表單的外部邊緣?
這是具有抓地力的設計師:
您可以通過創建自定義窗口樣式來做到這一點。 這是實現示例:
DropShadowedWindowStyle.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="DropShadowedWindow.DropShadowedWindowStyle">
<Style x:Key="DropShadowedWindowStyle" TargetType="{x:Type Window}">
<Setter Property="WindowStyle" Value="None"></Setter>
<Setter Property="AllowsTransparency" Value="True"></Setter>
<Setter Property="ResizeMode" Value="CanResize"></Setter>
<Setter Property="Background" Value="#FFF"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border Margin="10">
<Border.Effect>
<DropShadowEffect BlurRadius="10"/>
</Border.Effect>
<Grid>
<Border Background="{TemplateBinding Background}">
<ContentPresenter Name="ContentPresenter" ClipToBounds="True"></ContentPresenter>
</Border>
<Grid x:Name="ResizeDummies">
<Line Cursor="SizeNS" MouseDown="p_OnSizeN" X1="0" X2="{TemplateBinding ActualWidth}" StrokeThickness="4" Y1="0" Y2="0" Stroke="Transparent" VerticalAlignment="Top"></Line>
<Line Cursor="SizeNS" MouseDown="p_OnSizeS" X1="0" X2="{TemplateBinding ActualWidth}" StrokeThickness="4" Y1="{TemplateBinding ActualHeight}" Y2="{TemplateBinding ActualHeight}" Stroke="Transparent" VerticalAlignment="Bottom"></Line>
<Line Cursor="SizeWE" MouseDown="p_OnSizeW" X1="0" X2="0" StrokeThickness="4" Y1="0" Y2="{TemplateBinding ActualHeight}" Stroke="Transparent" HorizontalAlignment="Left"></Line>
<Line Cursor="SizeWE" MouseDown="p_OnSizeE" X1="{TemplateBinding ActualWidth}" X2="{TemplateBinding ActualWidth}" StrokeThickness="4" Y1="0" Y2="{TemplateBinding ActualHeight}" Stroke="Transparent" HorizontalAlignment="Right"></Line>
<Rectangle Cursor="SizeNWSE" MouseDown="p_OnSizeNW" Width="5" Height="5" Fill="Transparent" VerticalAlignment="Top" HorizontalAlignment="Left" />
<Rectangle Cursor="SizeNESW" MouseDown="p_OnSizeNE" Width="5" Height="5" Fill="Transparent" VerticalAlignment="Top" HorizontalAlignment="Right" />
<Rectangle Cursor="SizeNESW" MouseDown="p_OnSizeSW" Width="5" Height="5" Fill="Transparent" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
<Rectangle Cursor="SizeNWSE" MouseDown="p_OnSizeSE" Width="5" Height="5" Fill="Transparent" VerticalAlignment="Bottom" HorizontalAlignment="Right" />
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode" Value="CanMinimize">
<Setter TargetName="ResizeDummies" Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
<Trigger Property="ResizeMode" Value="NoResize">
<Setter TargetName="ResizeDummies" Property="Visibility" Value="Collapsed"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
DropShadowedWindowStyle.xaml.cs:
namespace DropShadowedWindow
{
public partial class DropShadowedWindowStyle
{
#region Helper Functions
/// <summary>
/// Return WinApi window handler from WPF window
/// </summary>
/// <param name="w"></param>
/// <returns></returns>
protected static IntPtr p_GetHW(Window w)
{
var helper = new WindowInteropHelper(w);
return helper.Handle;
}
/// <summary>
/// Get templated parent window, if it exists
/// </summary>
/// <param name="sender"></param>
protected Window p_GetTemplatedWindow(object sender)
{
var element = sender as FrameworkElement;
if (element != null)
{
var w = element.TemplatedParent as Window;
if (w != null) return w;
}
return null;
}
#endregion Helper Functions
#region Window Event Hanlders
protected enum SizingAction
{
North = 3,
South = 6,
East = 2,
West = 1,
NorthEast = 5,
NorthWest = 4,
SouthEast = 8,
SouthWest = 7
}
protected void p_OnSizeS(object sender, MouseButtonEventArgs e) { p_OnSize(sender, SizingAction.South); }
protected void p_OnSizeN(object sender, MouseButtonEventArgs e) { p_OnSize(sender, SizingAction.North); }
protected void p_OnSizeE(object sender, MouseButtonEventArgs e) { p_OnSize(sender, SizingAction.East); }
protected void p_OnSizeW(object sender, MouseButtonEventArgs e) { p_OnSize(sender, SizingAction.West); }
protected void p_OnSizeNW(object sender, MouseButtonEventArgs e) { p_OnSize(sender, SizingAction.NorthWest); }
protected void p_OnSizeNE(object sender, MouseButtonEventArgs e) { p_OnSize(sender, SizingAction.NorthEast); }
protected void p_OnSizeSE(object sender, MouseButtonEventArgs e) { p_OnSize(sender, SizingAction.SouthEast); }
protected void p_OnSizeSW(object sender, MouseButtonEventArgs e) { p_OnSize(sender, SizingAction.SouthWest); }
/// <summary>
/// Switch to resize mode by dragging corners
/// </summary>
/// <param name="sender"></param>
/// <param name="action"></param>
protected void p_OnSize(object sender, SizingAction action)
{
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
var w = p_GetTemplatedWindow(sender);
if (w != null && w.WindowState == WindowState.Normal) p_DragSize(p_GetHW(w), action);
}
}
#endregion Window Event Hanlders
#region P/Invoke
const int WmSyscommand = 0x112;
const int ScSize = 0xF000;
[DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
private static extern IntPtr p_SendMessage(IntPtr h_wnd, uint msg, IntPtr w_param, IntPtr l_param);
/// <summary>
/// Activate resize mode
/// </summary>
/// <param name="handle"></param>
/// <param name="sizing_action"></param>
private void p_DragSize(IntPtr handle, SizingAction sizing_action)
{
p_SendMessage(handle, WmSyscommand, (IntPtr)(ScSize + sizing_action), IntPtr.Zero);
p_SendMessage(handle, 514, IntPtr.Zero, IntPtr.Zero);
}
#endregion
}
}
注意:此示例不包含移動,關閉,最大化和最小化窗口的元素。 您可以在此項目https://github.com/D-Key/whosh或本文http://www.codeproject.com/Articles/140267/Create-Custom-Windows-in-WPF-with中查看如何做-緩解
您還可以在這里看到另一種方法: http : //social.msdn.microsoft.com/Forums/vstudio/en-US/02fb62be-4550-4036-8a72-fe53e43a6414/showing-resizegrip-on-a-window-with-一個影子
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.