Window类继承自 ContentControl 类,只能包含单个子元素,通常是一个布局。Window类的基本属性如下表:
属性名称 | 说明 |
---|---|
AllowsTransparency | 如果值为true,并且背景设置为透明色,允许其他窗口透过该窗口显示 |
Icon | 窗口图标的 ImageSource 对象 |
Top Left | 窗口左上角到屏幕顶部和左部之间的距离 |
ResizeMode | 用户是否可以改变窗口的尺寸 |
RestoreBounds | 获取窗口的边界,可表示位置和大小 |
ShowInTaskbar | 值为true时,会在任务栏和 Alt+Tab 列表中显示窗口 |
SizeToContent | 使用该属性创建自动放大自身尺寸的窗口 |
Title | 标题 |
Topmost | 总是显示在最前面 |
WindowStartupLocation | 窗体放置的位置 |
WindowState | 表示窗口是否被最大化,最小化或正常状态 |
WindowStyle | 决定窗口的边框 |
客户区是窗口边界内部的表面,可放置自定义内容。非客户区包括边框和窗口顶部的标题栏,由操作系统管理。
显示窗口
ShowDialog() 方法显示模态窗口,通过锁住所有鼠标和键盘输入来阻止用户访问父窗口,直到模态窗口被关闭。另外,直到窗口关闭,ShowDialog()方法才返回,中间一直阻塞。
Show() 方法显示非模态窗口,不会阻止用户访问其他任何窗口。Close() 方法关闭窗口,Hide()方法隐藏窗口。
定位窗口
System.Windows.SystemParameters 类可以用来检索有关屏幕实际大小的基本信息。
// 将窗口定位到屏幕*,和设置窗口状态为 CenterScreen 的效果相同
double screeHeight = SystemParameters.FullPrimaryScreenHeight;
double screeWidth = SystemParameters.FullPrimaryScreenWidth;
this.Top = (screenHeight - this.Height) / 2;
this.Left = (screenWidth - this.Width) / 2;
// 将窗口定位到可用屏幕区域的*,不包括停靠任务栏的区域
double workHeight = SystemParameters.WorkArea.Height;
double workWidth = SystemParameters.WorkArea.Width;
this.Top = (workHeight - this.Height) / 2;
this.Left = (workWidth - this.Width) / 2;
窗口交互
Application 类提供了用于访问其他窗口的两个工具: MainWindow 和 Windows 属性。
.Net允许一个窗口”拥有“其他窗口,当所有者最小化时被拥有者也自动最小化;当两者相互重叠时,被拥有者总显示在上面。
ToolWindow winTool = new ToolWindow();
winTool.Owner = this;
winTool.Show();
对话框模式可以给用户提供一些选择,代码等待选择结果然后执行相应的操作:
DialogWindow dialog = new DialogWindow();
if(dialog.ShowDialog() == true)
{
// 用户选择了确认
}
else
{
// 用户选择了取消
}
Windows操作系统提供了许多内置对话框,可通过Windows API访问这些对话框,WPF为其中几个对话框提供了封装程序。
- System.Windows.MessageBox
- PrintDialog
- OpenFileDialog
- SaveFileDialog
非矩形窗口
创建简单形状窗口需要以下几个步骤:
- 将 Window.AllowsTransparency 属性设置为 true
- 将 Window.WindowStyle 属性设置为 None.从而隐藏非客户区
- 将窗口背景设置为透明
这样就移除窗口的标准外观,然后就需要提供了一些不透明的具有所需形状的内容:
- 可以使用支持透明格式的文件提供背景插图
- 可以使用WPF中的形状绘制功能创建具有矢量内容的背景
- 可以使用简单的具有所需形状的WPF元素,比如Border
<Window WindowStyle="None" AllowsTransparency="True" Background="Transparent">
<Window.Background>
<ImageBrush ImageSource="squares.png"/>
</Window.Background>
</Window>
去掉标题栏后,窗体就没办法随鼠标进行拖动,需要手动调用 Window.DragMove() 方法。
将 Window.ResizeMode 属性设置为 CanResizeWithGrip时,会在窗口的右下角添加图形手柄(grip).如果想通过拖动窗口边缘来改变窗口的尺寸就需要其他的工作:
- 一种方法可以使用.NET的平台调用特性发送改变窗口尺寸的Win32消息
- 一种方法当用户拖动一条侧边时,简单跟踪鼠标位置并设置窗口的Width属性
此时就需要探测用户何时会将鼠标移动到窗口边缘,然后改变鼠标形状。
<Rectangle VerticalAlignment="Stretch" HorizontalAlignment="Right"
Cursor="SizeWE" Fill="Transparent"
MouseLeftButtonDown="window_initiateWiden"
MouseLeftButtonUp="window_endwiden"
MouseMove="window_Widen"/>
bool isWiden = false;
private void window_initiateWidth(object sender, MouseEventArgs e)
{
isWiden = true;
}
private void window_Widen(object sender, MouseEventArgs e)
{
Rectangle rect = (Rectangle)sender;
if (isWiden)
{
rect.CaptureMouse();
double newWidth = e.GetPosition(this).X + 5;
if (newWidth > 0) this.Width = newWidth;
}
}
private void window_endWiden(object sender, MouseEventArgs e)
{
isWiden = false;
Rectangle rect = (Rectangle)sender;
rect.ReleaseMouseCapture();
}
如果想把其他窗口都使用自定义窗口的话,可以使用控件模板。Widnow类的默认模板中包含 AdornerDecorator 元素,用于在窗口的其他客户内容之上创建一个特定的绘图区域,称之为装饰层。
<ControlTemplate x:Key="CustomWindowTemplate" TargetType="{x:Type Window}">
<Border Name="windowFrame" ...>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--窗体的 Title-->
<TextBlock Text="{TemplateBinding Title}" FontWeight="Bold"/>
<Button Style="{StaticResource CloseButton}" HorizontalAlignment="Right"/>
<!--窗体内容-->
<Border Grid.Row="1">
<AdornerDecorator>
<ContentPresenter/>
</AdornerDecorator>
</Border>
<!--底部-->
<ContentPresenter Grid.Row="2" Margin="10" HorizontalAlignment="Center"
Content="{TemplateBinding Tag}"/>
<!--改变大小-->
<ResizeGrip Name="WindowResizeGrip" Grid.Row="2" HorizontalAlignment="Right"
VerticalAlignment="Bottom" Visibility="Collapsed" IsTabStop="False"/>
<!--拖拽缩放的侧边-->
<Rectangle Grid.Row="1" Grid.RowSpan="3" Cursor="SizeWE"
VerticalAlignment="Stretch" HorizontalAlignment="Right"
Fill="Transparent" Width="5"/>
<Rectangle Grid.Row="2" Cursor="SizeNS"
VerticalAlignment="Bottom" HorizontalAlignment="Stretch"
Fill="Transparent" Height="5"/>
</Gird>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode" Value="CanResizeWithGrip">
<Setter TargetName="WindowResizeGrip" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="CustomWindowChrome" TargetType="{x:Type Window}">
<Setter Property="AllowsTransparency" Value="True"/>
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template" Value="{StaticResource CustomWidnowTemplate}"/>
</Style>
创建窗口,设置样式并填充一些基本内容:
<Window ...
Title="CustomWindowTest"
Style="{StaticResource CustomWindowChrome}">
<StackPanel Margin="10">
<TextBlock Margin="3">This is a test.</TextBlock>
</StackPanel>
</Window>