一般情况下给窗口设置四个属性就可以了,如下代码所示:
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaApplication1.MainWindow"
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
ExtendClientAreaTitleBarHeightHint="-1"
SystemDecorations="None"
Background="Green"
Width="800"
Height="600"
Title="AvaloniaApplication1">
<StackPanel>
<Rectangle Fill="Blue" Height="50" />
<Rectangle Fill="Green" Height="600"/>
</StackPanel>
</Window>
ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="NoChrome"
ExtendClientAreaTitleBarHeightHint="-1"
SystemDecorations="None"
这样设置后,窗口就变成了无边框窗口了,虽然可以支持调整大小,但没有窗口阴影。
要做窗口阴影,得用原生Win32 API,下面是暴露Win32 API的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace AvaloniaApplication1
{
internal static class Native
{
[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
[DllImport("dwmapi.dll")]
public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
[DllImport("dwmapi.dll")]
public static extern int DwmIsCompositionEnabled(out bool pfEnabled);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);
[Flags]
public enum SetWindowPosFlags : uint
{
SWP_ASYNCWINDOWPOS = 0x4000,
SWP_DEFERERASE = 0x2000,
SWP_DRAWFRAME = 0x0020,
SWP_FRAMECHANGED = 0x0020,
SWP_HIDEWINDOW = 0x0080,
SWP_NOACTIVATE = 0x0010,
SWP_NOCOPYBITS = 0x0100,
SWP_NOMOVE = 0x0002,
SWP_NOOWNERZORDER = 0x0200,
SWP_NOREDRAW = 0x0008,
SWP_NOREPOSITION = 0x0200,
SWP_NOSENDCHANGING = 0x0400,
SWP_NOSIZE = 0x0001,
SWP_NOZORDER = 0x0004,
SWP_SHOWWINDOW = 0x0040
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref RECT pvParam, uint fWinIni);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
}
}
下面是使用这些API的代码(窗口类的代码)
using Avalonia.Controls;
using System;
namespace AvaloniaApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += (e, s) =>
{
updateWin32Border(this.WindowState);
};
this.PropertyChanged += (s, e) =>
{
if (e.Property == Window.WindowStateProperty)
{
switch ((WindowState)e.NewValue)
{
case WindowState.Maximized:
updateWin32Border(this.WindowState);
break;
}
}
};
}
void updateWin32Border(WindowState v)
{
if (v == WindowState.Maximized)
{
var workArea = new Native.RECT();
Native.SystemParametersInfo(0x0030, 0, ref workArea, 0);
Native.SetWindowPos(this.TryGetPlatformHandle().Handle, IntPtr.Zero,
0, 0,
workArea.Right - workArea.Left-1,
workArea.Bottom - workArea.Top-1,
Native.SetWindowPosFlags.SWP_NOZORDER | Native.SetWindowPosFlags.SWP_NOACTIVATE);
}
else
{
var margins = new Native.MARGINS
{
cyBottomHeight = 1,
cxRightWidth = 1,
cxLeftWidth = 1,
cyTopHeight = 1
};
Native.DwmExtendFrameIntoClientArea(this.TryGetPlatformHandle().Handle, ref margins);
}
}
}
}
这些工作做完之后,窗口就有阴影了,如下图所示: