我想在这里添加一个免责声明,我出于好奇很快就把它放在一起,最重要的是。除了在其中放置一些控件并运行它之外,我还没有测试过这么多。它有效,但不应被视为完全完整。我也认为可能有更好的方法来做到这一点,但我认为这至少会给你一个好的起点。
向您的项目添加一个新的ResourceDictionary,并添加以下 XAML:
<ResourceDictionary
x:Class="CustomWindow.BaseResource"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="WindowStyle" TargetType="{x:Type Window}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="ResizeMode" Value="NoResize" />
<Setter Property="Background" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Border
x:Name="WindowBorder"
BorderBrush="Black"
BorderThickness="1">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="White" />
<GradientStop Offset="1" Color="#FFDADADA" />
</LinearGradientBrush>
</Border.Background>
<Grid
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Cursor="Arrow">
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
Width="500"
Height="23"
Margin="11,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Text="{TemplateBinding Title}" />
<Rectangle
x:Name="TitleBar"
Fill="Transparent"
MouseDown="TitleBar_MouseDown" />
<Rectangle
Grid.RowSpan="2"
Width="10"
HorizontalAlignment="Left"
Cursor="SizeWE"
Fill="Transparent"
MouseDown="Border_MouseDown"
Tag="Left" />
<Rectangle
Grid.RowSpan="2"
Width="10"
HorizontalAlignment="Right"
Cursor="SizeWE"
Fill="Transparent"
MouseDown="Border_MouseDown"
Tag="Right" />
<Rectangle
Height="5"
VerticalAlignment="Top"
Cursor="SizeNS"
Fill="Transparent"
MouseDown="Border_MouseDown"
Tag="Top" />
<Rectangle
Grid.Row="1"
Height="10"
VerticalAlignment="Bottom"
Cursor="SizeNS"
Fill="Transparent"
MouseDown="Border_MouseDown"
Tag="Bottom" />
<StackPanel
Margin="10,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Orientation="Horizontal">
<Button
x:Name="MinimizeButton"
Width="43"
Height="17"
Click="MinimizeButton_Click"
IsTabStop="False">
min
</Button>
<Button
x:Name="MaximizeButton"
Width="43"
Height="17"
Margin="5,0"
Click="MaximizeButton_Click"
IsTabStop="False">
max
</Button>
<Button
x:Name="CloseButton"
Width="43"
Height="17"
Click="CloseButton_Click"
IsTabStop="False">
<Path
Width="12"
Height="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M0.5,0.5L4.5178828,0.5 6.0620003,3.125 7.4936447,
0.5 11.5,0.5 11.5,1.5476431 8.7425003,6.1201854 11.5,
10.359666 11.5,11.5 7.4941902,11.5 6.0620003,8.8740005
4.5172949,11.5 0.5,11.5 0.5,10.43379 3.3059995,
6.1201582 0.5,1.4676378 0.5,0.5z"
Fill="#E4FFFFFF"
Stretch="Fill"
Stroke="#FF535666" />
</Button>
</StackPanel>
<Border
Grid.Row="1"
Margin="10,0,10,10"
BorderBrush="Black"
BorderThickness="1">
<Grid>
<Rectangle Fill="White" />
<ContentPresenter Content="{TemplateBinding Content}" />
</Grid>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
出于说明目的,假设我们将 ResourceDictionary 命名为 BaseResource.xaml。
接下来将新类添加到您添加资源的同一目录中,并将文件命名为 BaseResource.xaml.cs,替换 XAML 文件的实际名称。
返回 BaseResource.xaml 并将 x:Class="CustomWindow.BaseResource" 属性更改为 ResourceDictionary 的完整类型名称。如果更改正确,Visual Studio 应该抱怨 BaseResource.xaml.cs 中有重复的定义。通过将 partial 关键字修饰符添加到 .cs 文件中的类来解决此问题。
最后在代码文件中添加如下代码:
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
namespace CustomWindow
{
public partial class BaseResource
{
private const uint WM_SYSCOMMAND = 0x112;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr
SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
e.Handled = true;
Window.GetWindow((DependencyObject) sender).Close();
}
private void MinimizeButton_Click(object sender, RoutedEventArgs e)
{
e.Handled = true;
Window.GetWindow((DependencyObject) sender).WindowState = WindowState.Minimized;
}
private void MaximizeButton_Click(object sender, RoutedEventArgs e)
{
e.Handled = true;
var window = Window.GetWindow((DependencyObject) sender);
window.WindowState =
(window.WindowState == WindowState.Maximized) ? WindowState.Normal : WindowState.Maximized;
}
private void TitleBar_MouseDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
Window.GetWindow((DependencyObject) sender).DragMove();
}
private void Border_MouseDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
var direction = (Direction)Enum.Parse(typeof(Direction), ((FrameworkElement)sender).Tag.ToString());
ResizeWindow(PresentationSource.FromVisual((Visual)sender) as HwndSource, direction);
}
private void ResizeWindow(HwndSource hwndSource, Direction direction)
{
SendMessage(hwndSource.Handle, WM_SYSCOMMAND, (int)(61440 + direction), 0);
}
private enum Direction
{
Left = 1,
Right = 2,
Top = 3,
TopLeft = 4,
TopRight = 5,
Bottom = 6,
BottomLeft = 7,
BottomRight = 8,
}
}
}
接下来将 ResourceDictionary 添加到全局应用程序资源。同样,用你的文件名替换 BaseResource.xaml,如果它不同的话。
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BaseResource.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
将样式添加到目标窗口。
<Window
...
Style="{StaticResource WindowStyle}">
一些事情......
设计者在没有内容的情况下乱了样式。可能是因为我在哪里放置了高度和宽度的 TemplateBinding,但是在运行时它看起来很好,所以我没有进一步弄乱它。我也没有实现角的调整大小,但添加到模板中很容易。
最后,我没有为最小化和最大化按钮绘制图标。我不擅长在 Blend 中创建路径。
希望对你有帮助。