-
C#关于WPF窗口创建——基础界面设计
第二部分:桌面应用开发
12.WPF窗口创建——基础界面设计
实例介绍
你有没有想过做一个任务管理工具的主界面?比如像Windows自带的“待办事项”那样,但更个性化。WPF(Windows Presentation Foundation)是.NET平台下最适合做桌面应用界面的框架——它支持矢量图形(缩放不失真)、数据绑定(界面自动更新)、MVVM架构(代码分离),能轻松做出美观且易维护的界面。
举个真实例子:之前团队做任务管理工具时,先用WinForms写了个原型,但界面丑、布局难调,后来换成WPF,只用了半天就重构出了美观的界面,而且数据绑定让后续功能扩展变得很简单。这一节,我们就从0开始,带你做一个任务管理工具的主界面,掌握WPF窗口创建和基础布局的核心技巧。
需求分析
一个基础的任务管理主界面需要包含以下元素:
1.窗口基础属性:标题(“任务管理工具”)、初始大小(800×600)、启动位置(屏幕中央)、是否可最大化/最小化;
2.布局结构:
1.顶部:菜单栏(“文件”“编辑”“帮助”)+ 工具栏(“添加任务”“删除任务”按钮);
2.中间:任务列表区域(用DataGrid展示任务标题、截止日期、状态);
3.底部:状态栏(显示当前时间、任务总数);
3.交互功能:点击“添加任务”按钮弹出对话框(后续章节实现);
4.界面美观:按钮有 hover 效果、DataGrid有交替行颜色、窗口有阴影效果。
目标:用WPF的XAML和C#代码,快速搭建一个结构清晰、美观易用的基础界面,为后续功能扩展打下基础。
代码实现
前置条件:.NET 6+、Visual Studio 2022(带WPF开发工具);需创建WPF应用项目(模板选择“WPF App (.NET)”)。
场景1:创建空窗口(最基础的WPF窗口)
XAML代码(MainWindow.xaml)
xml
<Window x:Class="TaskManager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="任务管理工具" <!-- 窗口标题 -->
Width="800" Height="600" <!-- 初始大小 -->
StartupLocation="CenterScreen" <!-- 启动位置:屏幕中央 -->
WindowStyle="SingleBorderWindow" <!-- 窗口样式:标准边框 -->
ResizeMode="CanResizeWithGrip"> <!-- 可调整大小(带右下角 grip) -->
<!-- 窗口内容区域:暂时为空,后续添加布局 -->
<Grid>
</Grid>
</Window>
C#后台代码(MainWindow.xaml.cs)
csharp
using System.Windows;
namespace TaskManager
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent(); // 必须调用:初始化XAML定义的界面元素
}
}
}
场景2:添加布局容器(Grid分区域)
WPF的布局核心是容器控件,Grid适合复杂布局(分行列)。我们把窗口分成4行:
第1行:菜单栏(高度Auto,随内容调整);
第2行:工具栏(高度Auto);
第3行:任务列表(高度*,占剩余空间);
第4行:状态栏(高度Auto)。
XAML代码(更新MainWindow.xaml的Grid部分)
xml
<Grid>
<!-- 定义4行 -->
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <!-- 菜单栏行 -->
<RowDefinition Height="Auto"/> <!-- 工具栏行 -->
<RowDefinition Height="*"/> <!-- 任务列表行(占剩余空间) -->
<RowDefinition Height="Auto"/> <!-- 状态栏行 -->
</Grid.RowDefinitions>
<!-- 1. 菜单栏 -->
<Menu Grid.Row="0" Background="#F0F0F0">
<MenuItem Header="文件">
<MenuItem Header="新建任务"/>
<MenuItem Header="退出"/>
</MenuItem>
<MenuItem Header="编辑">
<MenuItem Header="修改任务"/>
<MenuItem Header="删除任务"/>
</MenuItem>
<MenuItem Header="帮助">
<MenuItem Header="关于"/>
</MenuItem>
</Menu>
<!-- 2. 工具栏 -->
<ToolBar Grid.Row="1" Background="#F5F5F5">
<Button Content="添加任务" Width="80" Margin="5" Click="AddTaskButton_Click"/>
<Button Content="删除任务" Width="80" Margin="5"/>
</ToolBar>
<!-- 3. 任务列表(DataGrid) -->
<DataGrid Grid.Row="2" x:Name="TaskDataGrid" Margin="10"
AlternatingRowBackground="#E8F4FF" <!-- 交替行颜色 -->
CanUserAddRows="False" <!-- 禁止用户手动添加行 -->
AutoGenerateColumns="False"> <!-- 手动定义列 -->
<DataGrid.Columns>
<DataGridTextColumn Header="任务标题" Binding="{Binding Title}" Width="*"/>
<DataGridTextColumn Header="截止日期" Binding="{Binding DueDate, StringFormat='yyyy-MM-dd'}" Width="150"/>
<DataGridCheckBoxColumn Header="已完成" Binding="{Binding IsCompleted}" Width="80"/>
</DataGrid.Columns>
</DataGrid>
<!-- 4. 状态栏 -->
<StatusBar Grid.Row="3" Background="#F0F0F0" Height="25">
<TextBlock x:Name="StatusText" Text="就绪 | 任务总数:0"/>
</StatusBar>
</Grid>
场景3:处理按钮点击事件(C#代码)
给“添加任务”按钮添加点击事件,弹出消息框(后续章节替换为任务添加窗口)。
C#代码(更新MainWindow.xaml.cs)
csharp
using System.Windows;
namespace TaskManager
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// 模拟加载任务数据(后续替换为真实数据)
LoadSampleTasks();
}
// 加载模拟任务数据
private void LoadSampleTasks()
{
var tasks = new List<TaskItem>
{
new TaskItem { Title = "学习WPF", DueDate = DateTime.Now.AddDays(3), IsCompleted = false },
new TaskItem { Title = "写单元测试", DueDate = DateTime.Now.AddDays(5), IsCompleted = true }
};
TaskDataGrid.ItemsSource = tasks;
// 更新状态栏
StatusText.Text = $"就绪 | 任务总数:{tasks.Count}";
}
// 点击“添加任务”按钮的事件处理
private void AddTaskButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("点击了添加任务按钮(后续章节实现对话框)", "提示");
}
}
// 模拟任务实体(后续替换为真实实体)
public class TaskItem
{
public string Title { get; set; } = string.Empty;
public DateTime DueDate { get; set; }
public bool IsCompleted { get; set; }
}
}
逐行讲解
场景1:空窗口
1.XAML头部:xmlns是命名空间声明,xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"是WPF核心控件的命名空间,xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"是XAML语法扩展的命名空间;
2.Window属性:
oTitle:窗口标题;
oWidth/Height:初始大小;
oStartupLocation="CenterScreen":启动时居中;
oResizeMode="CanResizeWithGrip":允许调整大小,右下角显示调整手柄;
3.C#代码:InitializeComponent()是自动生成的方法,负责加载XAML定义的界面元素,必须在构造函数中调用。
场景2:Grid布局
1.Grid.RowDefinitions:定义4行,Height="Auto"表示高度随内容变化,Height="*"表示占剩余空间;
2.Menu控件:Grid.Row="0"指定放在第1行,Background="#F0F0F0"设置背景色;MenuItem是菜单子项,Header是显示文本;
3.ToolBar控件:Grid.Row="1"放在第2行,Button的Margin="5"设置四周间距,Click="AddTaskButton_Click"绑定点击事件;
4.DataGrid控件:Grid.Row="2"放在第3行,x:Name="TaskDataGrid"给控件命名(方便后台代码访问);AlternatingRowBackground设置交替行颜色,AutoGenerateColumns="False"手动定义列;DataGridTextColumn绑定任务实体的属性(如Binding="{Binding Title}")。
场景3:事件处理
1.LoadSampleTasks方法:模拟加载任务数据,TaskDataGrid.ItemsSource = tasks把数据绑定到DataGrid;
2.AddTaskButton_Click方法:按钮点击事件的处理逻辑,用MessageBox.Show弹出提示框;
3.TaskItem类:模拟任务实体,后续会和之前的TaskService结合,使用真实数据。
基础知识拓展
-
WPF核心概念
概念 说明
XAML 可扩展应用程序标记语言,用于定义WPF界面,和C#代码分离,易维护;
布局容器 - Grid:分行列,适合复杂布局;- StackPanel:线性排列(水平/垂直);- WrapPanel:自动换行排列;- DockPanel:停靠布局(上/下/左/右);
依赖属性 WPF特有的属性系统,支持数据绑定、动画、样式;比如Width是依赖属性,可绑定到其他控件的属性;
数据绑定 界面元素自动同步数据,比如DataGrid的ItemsSource绑定到任务列表,数据变化时界面自动更新;
路由事件 事件可在控件树中传递(冒泡/隧道),比如点击按钮的事件可被父容器捕获; - WPF vs WinForms
| 特性 | WPF | WinForms |
|---|---|---|
| 界面设计 | XAML+C#分离,易维护 | 代码生成界面,耦合度高 |
| 布局系统 | 灵活的容器布局 | 固定位置布局,难适配不同分辨率 |
| 美观度 | 支持矢量图形、渐变、阴影,界面更美观 | 原生控件,样式单一 |
| 数据绑定 | 强大的数据绑定支持 | 弱数据绑定,需手动更新界面 |
| 架构支持 | 天然支持MVVM架构 | 适合传统的事件驱动架构 |
-
界面设计最佳实践
1.优先用Grid布局:复杂界面用Grid分区域,简单线性布局用StackPanel;
2.避免固定大小:用和Auto适应不同窗口大小,比如DataGrid的Width=""占满剩余宽度;
3.使用样式统一界面:用Style定义按钮、文本框的统一样式,避免重复代码;
4.数据绑定代替手动更新:减少代码量,提高可维护性;
5.测试不同分辨率:确保界面在不同屏幕大小下正常显示。
总结
本节通过任务管理工具的主界面,带你掌握了WPF窗口创建和基础布局的核心技巧:
1.窗口基础属性:设置标题、大小、启动位置;
2.布局容器:用Grid分行列,组织界面结构;
3.UI元素:添加Menu、ToolBar、DataGrid等控件;
4.事件处理:绑定按钮点击事件,实现交互逻辑;
5.数据绑定:DataGrid绑定任务数据,界面自动更新。
WPF的优势在于界面美观、布局灵活、数据绑定强大,后续章节会深入讲解MVVM架构和数据绑定,让你写出更专业的WPF应用。
本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49459.html










