WPF 从入门到实践:基础、ModernUI 与 MVVM 完全指南
第一部分:WPF 基础操作(手把手教学)
在这一部分,我们将从零开始创建一个WPF应用程序,逐一学习最常用的控件和布局,并了解每个环节的注意事项。
第1步:创建你的第一个WPF项目
- 打开 Visual Studio(推荐 2019 或 2022)。
- 选择 创建新项目 → 搜索 WPF → 选择 WPF 应用程序 (.NET Core) 或 WPF 应用程序 (.NET Framework)(推荐 .NET Core/.NET 5/6/7/8,跨平台且性能更好)。
- 项目名称输入
WpfDemo,选择保存位置,点击 创建。
项目结构简介:
App.xaml:应用程序的入口,定义全局资源和启动逻辑。MainWindow.xaml:主窗口的界面设计文件。MainWindow.xaml.cs:主窗口的后台代码文件(通常称为 code-behind)。
注意事项:
- 如果是 .NET Core 版本,
App.xaml中默认不包含StartupUri,需要手动添加或修改Main方法来指定启动窗口。 - 建议一开始就熟悉这两个文件的作用,后面会频繁使用。
第2步:认识 XAML 和基本控件
打开 MainWindow.xaml,您会看到类似下面的代码:
xml
<Window x:Class="WpfDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
</Window>
<Grid> 是一个布局容器,所有控件都要放在布局容器内。
2.1 添加一个文本块(TextBlock)
在 <Grid> 中添加一个 TextBlock:
xml
<Grid>
<TextBlock Text="欢迎学习WPF"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="20"
Foreground="Blue"/>
</Grid>
注意事项:
HorizontalAlignment和VerticalAlignment用于控制控件在容器内的对齐方式。- 属性值可以直接写在标签内,也可以使用属性元素语法(复杂对象时使用)。
- 所有 XAML 元素都必须正确关闭(自关闭或成对关闭)。
2.2 添加一个按钮(Button)并处理点击事件
在 Grid 中添加一个按钮,并为其添加点击事件:
xml
<Button Content="点我"
Width="100" Height="30"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Click="Button_Click"/>
然后按 F12 或右键点击 Click="Button_Click" 选择"转到定义",Visual Studio 会自动在 MainWindow.xaml.cs 中生成事件处理程序:
csharp
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("按钮被点击了!");
}
注意事项:
- 事件名称可以任意,但通常采用
控件名_事件名的命名方式。 - 在 XAML 中写
Click="Button_Click"后,编译时会自动检查后台是否有匹配的方法,如果没有会报错。 - 事件处理程序的方法签名必须匹配委托定义(通常是
object sender, RoutedEventArgs e)。
2.3 文本框(TextBox)和密码框(PasswordBox)
添加一个文本框和一个密码框,并在按钮点击时获取它们的值。
xml
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBox x:Name="UserNameTextBox" Width="200" Margin="5" Placeholder="请输入用户名"/>
<PasswordBox x:Name="PasswordBox" Width="200" Margin="5" PasswordChar="*"/>
<Button Content="登录" Width="100" Margin="5" Click="LoginButton_Click"/>
</StackPanel>
后台代码:
csharp
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
string userName = UserNameTextBox.Text;
string password = PasswordBox.Password;
MessageBox.Show($"用户名:{userName},密码:{password}");
}
注意事项:
x:Name属性用于在后台代码中引用该控件。Placeholder不是 TextBox 的固有属性,WPF 原生不支持占位符文本,但可以通过样式或第三方库实现。上面的Placeholder仅为示意,实际需使用Tag或附加属性,或者使用Watermark控件。PasswordBox.Password是明文密码,请注意安全性(如果确实需要获取明文)。
2.4 列表控件(ListBox、ComboBox)
添加一个 ListBox 并绑定数据:
xml
<ListBox x:Name="FruitListBox" Width="200" Height="100" Margin="5" DisplayMemberPath="Name"/>
在窗口加载时填充数据(MainWindow 构造函数中):
csharp
public MainWindow()
{
InitializeComponent();
FruitListBox.ItemsSource = new List<Fruit>
{
new Fruit { Name = "苹果", Price = 5.5 },
new Fruit { Name = "香蕉", Price = 3.2 },
new Fruit { Name = "橙子", Price = 4.8 }
};
}
public class Fruit
{
public string Name { get; set; }
public double Price { get; set; }
}
如果要显示多个属性,可以自定义 ItemTemplate:
xml
<ListBox x:Name="FruitListBox" Width="200" Height="100" Margin="5">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Width="60"/>
<TextBlock Text="{Binding Price}" Margin="5,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
注意事项:
ItemsSource可以绑定任何实现了IEnumerable的集合。- 若要界面随数据变化自动更新,应使用
ObservableCollection<T>而不是List<T>。 DataTemplate定义了每个列表项的呈现方式,使用{Binding Path}绑定数据对象的属性。
2.5 布局容器详解
WPF 提供多种布局面板,掌握它们能灵活设计界面。
-
Grid :表格布局,可定义行和列。
xml<Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Text="行0列0"/> <TextBlock Grid.Row="0" Grid.Column="1" Text="行0列1"/> <TextBlock Grid.Row="1" Grid.ColumnSpan="2" Text="跨两列"/> </Grid> -
StackPanel:水平或垂直堆叠。
-
DockPanel:控件可停靠在上、下、左、右。
-
WrapPanel:自动换行排列。
-
Canvas:绝对定位。
注意事项:
- 使用
Grid时,若不指定RowDefinitions和ColumnDefinitions,则默认为单行单列。 *表示按比例分配剩余空间,Auto表示根据内容自动调整大小。
2.6 数据绑定(基础)
WPF 最强大的特性之一就是数据绑定。让我们创建一个简单的绑定示例。
在 MainWindow.xaml 中添加一个滑块和一个文本块,使文本块显示滑块的当前值:
xml
<StackPanel Margin="10">
<Slider x:Name="MySlider" Minimum="0" Maximum="100" Value="50"/>
<TextBlock Text="{Binding ElementName=MySlider, Path=Value}"
FontSize="20" HorizontalAlignment="Center"/>
</StackPanel>
这里使用了 ElementName 绑定,将 TextBlock.Text 绑定到 MySlider.Value。移动滑块时,文本自动更新。
注意事项:
- 绑定的默认模式是
OneWay(单向),但TextBox.Text默认是TwoWay(双向)。 - 可通过
Mode属性指定绑定模式:OneTime、OneWay、TwoWay、OneWayToSource。
2.7 样式和资源
使用样式可以统一控件外观。在 App.xaml 或窗口资源中定义样式。
xml
<Window.Resources>
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Padding" Value="10,5"/>
</Style>
</Window.Resources>
<Button Content="样式按钮" Style="{StaticResource MyButtonStyle}"/>
注意事项:
x:Key为样式指定唯一键,通过{StaticResource}或{DynamicResource}引用。- 如果不指定
x:Key,样式会自动应用于该类型的所有控件(隐式样式)。
第3步:综合小案例------简易登录界面
将以上知识综合,创建一个简单的登录界面,包含用户名、密码、登录按钮和状态提示。
MainWindow.xaml:
xml
<Window x:Class="WpfDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="登录系统" Height="250" Width="300" WindowStartupLocation="CenterScreen">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- 用户名 -->
<Label Grid.Row="0" Grid.Column="0" Content="用户名:" VerticalAlignment="Center"/>
<TextBox x:Name="UserNameTextBox" Grid.Row="0" Grid.Column="1" Margin="5" Height="25"/>
<!-- 密码 -->
<Label Grid.Row="1" Grid.Column="0" Content="密码:" VerticalAlignment="Center"/>
<PasswordBox x:Name="PasswordBox" Grid.Row="1" Grid.Column="1" Margin="5" Height="25"/>
<!-- 登录按钮 -->
<Button x:Name="LoginButton" Grid.Row="2" Grid.ColumnSpan="2"
Content="登录" Width="80" Height="30" HorizontalAlignment="Center"
Margin="5" Click="LoginButton_Click"/>
<!-- 状态信息 -->
<TextBlock x:Name="StatusText" Grid.Row="3" Grid.ColumnSpan="2"
Text="" Foreground="Red" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Window>
MainWindow.xaml.cs:
csharp
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
string userName = UserNameTextBox.Text;
string password = PasswordBox.Password;
// 简单的验证逻辑
if (userName == "admin" && password == "123456")
{
StatusText.Text = "登录成功!";
StatusText.Foreground = System.Windows.Media.Brushes.Green;
}
else
{
StatusText.Text = "用户名或密码错误!";
StatusText.Foreground = System.Windows.Media.Brushes.Red;
}
}
}
注意事项:
WindowStartupLocation="CenterScreen"使窗口启动时居中显示。Grid.ColumnSpan="2"让按钮跨越两列。- 这里直接使用 code-behind 处理逻辑,后续 MVVM 部分会重构为更优雅的方式。
第二部分:ModernUI------让界面更现代
2.1 什么是 ModernUI
ModernUI(也称 Fluent Design)是微软为 Windows 应用推荐的现代设计语言,特点是简洁、流畅、富有动感。在 WPF 中,我们可以通过第三方库快速实现这种风格,其中最流行的是 ModernWpfUI(原 MahApps.Metro 的进化版)。
2.2 集成 ModernWpfUI
步骤 1:安装 NuGet 包
在项目中右键"管理 NuGet 程序包",搜索并安装 ModernWpfUI。
步骤 2:修改 App.xaml,引入主题资源
xml
<Application x:Class="WpfDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- 引入 ModernWpf 主题 -->
<ResourceDictionary Source="pack://application:,,,/ModernWpf;component/Theme/ThemeResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
步骤 3:为窗口启用现代样式
修改 MainWindow.xaml:
xml
<Window x:Class="WpfDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.modernwpf.com/2019"
ui:WindowHelper.UseModernWindowStyle="True"
Title="ModernUI 示例" Height="350" Width="500">
<Grid Margin="10">
<!-- 这里放置控件,它们会自动获得现代样式 -->
<StackPanel>
<TextBox PlaceholderText="请输入内容" Margin="5"/>
<PasswordBox PlaceholderText="请输入密码" Margin="5"/>
<Button Content="现代按钮" Style="{StaticResource AccentButtonStyle}" Margin="5"/>
<CheckBox Content="复选框" Margin="5"/>
<RadioButton Content="单选" Margin="5"/>
</StackPanel>
</Grid>
</Window>
注意事项:
ui:WindowHelper.UseModernWindowStyle="True"启用现代窗口样式,包括圆角、标题栏等。PlaceholderText是 ModernWpf 为TextBox和PasswordBox新增的附加属性,用于显示占位文本。AccentButtonStyle是预定义的强调按钮样式。
2.3 支持暗色主题
ModernWpfUI 支持自动跟随系统主题或手动切换。在 App.xaml 中添加主题管理器资源:
xml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ModernWpf;component/Theme/ThemeResources.xaml"/>
<!-- 可选:添加主题管理器 -->
<ResourceDictionary Source="pack://application:,,,/ModernWpf;component/Theme/ThemeManager.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
然后在代码中可以通过 ThemeManager.Current.SetTheme(Theme.Light) 等方式切换主题。
注意事项:
- 如果手动切换主题,需确保在 App 启动时已加载主题资源。
- 可以在按钮点击事件中调用
ThemeManager.Current.SetTheme实现亮/暗切换。
第三部分:MVVM 模式与 Prism 框架
3.1 为什么需要 MVVM
随着业务逻辑复杂化,将大量代码写在 Window 的 code-behind 中会导致:
- 难以单元测试:UI 元素依赖导致无法单独测试逻辑。
- 耦合度高:修改界面可能影响逻辑,反之亦然。
- 代码复用困难:类似逻辑难以在不同 View 中共享。
MVVM 模式通过数据绑定和命令将 View 和 ViewModel 解耦,让开发者专注于业务逻辑。
3.2 MVVM 核心概念
- View:负责界面呈现,通常使用 XAML 定义,包含控件和绑定。
- ViewModel :负责界面逻辑和数据状态,实现
INotifyPropertyChanged接口,以便属性变更时通知 View 更新。 - Model:数据模型,通常包含业务实体和数据访问层。
3.3 Prism 框架简介
Prism 是一个功能强大的 MVVM 框架,提供以下核心功能:
- 依赖注入容器(基于 Unity 或 DryIoc)
- 命令(DelegateCommand)
- 区域导航(Region)
- 模块化开发(Module)
- 对话框服务(DialogService)
- 事件聚合器(EventAggregator)
3.4 创建第一个 Prism 项目
步骤 1:安装 Prism 模板(可选)
在 Visual Studio 中搜索并安装 Prism Template Pack,可以快速创建 Prism 项目。
步骤 2:手动创建 Prism 项目
创建一个新的 WPF 项目,然后通过 NuGet 安装 Prism.DryIoc(或 Prism.Unity,这里以 DryIoc 为例)。
步骤 3:修改 App.xaml 和 App.xaml.cs
删除 App.xaml 中的 StartupUri,并修改为派生自 PrismApplication:
xml
<prism:PrismApplication x:Class="WpfDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/">
<Application.Resources>
</Application.Resources>
</prism:PrismApplication>
App.xaml.cs:
csharp
using System.Windows;
using Prism.DryIoc;
using Prism.Ioc;
using WpfDemo.Views;
namespace WpfDemo
{
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
// 注册服务和视图
}
}
}
3.5 实现一个简单的登录功能(MVVM 方式)
3.5.1 创建 ViewModel
在项目中新建文件夹 ViewModels,添加 MainWindowViewModel.cs:
csharp
using Prism.Mvvm;
using Prism.Commands;
using System.Windows;
namespace WpfDemo.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private string _userName;
public string UserName
{
get { return _userName; }
set { SetProperty(ref _userName, value); }
}
private string _password;
public string Password
{
get { return _password; }
set { SetProperty(ref _password, value); }
}
private string _statusMessage;
public string StatusMessage
{
get { return _statusMessage; }
set { SetProperty(ref _statusMessage, value); }
}
public DelegateCommand LoginCommand { get; private set; }
public MainWindowViewModel()
{
LoginCommand = new DelegateCommand(ExecuteLogin, CanExecuteLogin);
}
private void ExecuteLogin()
{
if (UserName == "admin" && Password == "123456")
{
StatusMessage = "登录成功!";
}
else
{
StatusMessage = "用户名或密码错误!";
}
}
private bool CanExecuteLogin()
{
return !string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password);
}
}
}
3.5.2 修改 View(MainWindow.xaml)
将 MainWindow 的 DataContext 设置为 ViewModel(通常在 XAML 中通过 d:DataContext 设计时支持,实际运行时由容器注入):
xml
<Window x:Class="WpfDemo.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
xmlns:viewModels="clr-namespace:WpfDemo.ViewModels"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="Prism MVVM 登录" Height="250" Width="300">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="用户名:"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged}" Margin="5"/>
<Label Grid.Row="1" Grid.Column="0" Content="密码:"/>
<PasswordBox x:Name="PasswordBox" Grid.Row="1" Grid.Column="1" Margin="5"/>
<Button Grid.Row="2" Grid.ColumnSpan="2" Content="登录"
Command="{Binding LoginCommand}"
Width="80" Height="30" HorizontalAlignment="Center" Margin="5"/>
<TextBlock Grid.Row="3" Grid.ColumnSpan="2" Text="{Binding StatusMessage}"
Foreground="Red" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Window>
注意 :PasswordBox 的密码不能直接绑定,因为 Password 属性不是依赖属性。Prism 提供了附加属性来解决这个问题,或者我们可以在命令执行时手动获取密码。这里我们采用手动方式,修改 ViewModel 和 View:
在 MainWindow.xaml.cs 中为 PasswordBox 添加一个名称,并在 ViewModel 中添加一个属性来接收密码(通过命令参数传递)。
更好的做法是使用 Prism 的 PasswordBoxHelper 附加属性(需要引入命名空间)。这里为简化,我们直接在后代码中将密码传递给 ViewModel。
修改 View:
xml
<PasswordBox x:Name="PasswordBox" Grid.Row="1" Grid.Column="1" Margin="5"/>
修改 LoginCommand 执行时获取密码:
csharp
private void ExecuteLogin()
{
// 如何获取密码?可以在 View 中调用 ViewModel 的方法,但会破坏解耦。
// 最佳实践:使用 Prism 的 Interaction 或 Behavior,或者使用附加属性。
// 简单起见,我们可以在 View 的 code-behind 中处理按钮点击,并调用 ViewModel 的方法。
}
为了保持纯净的 MVVM,我们使用 Prism 的 PasswordBoxHelper(需要安装 Prism.Wpf 包):
在 XAML 中添加命名空间:
xml
xmlns:prism="http://prismlibrary.com/"
为 PasswordBox 添加附加属性:
xml
<PasswordBox prism:PasswordBoxHelper.Password="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
然后 ViewModel 中的 Password 属性就可以自动获取输入了。
注意事项:
ViewModelLocator.AutoWireViewModel="True"会自动根据命名规则找到对应的 ViewModel(View 同名且位于 ViewModels 文件夹下)。- 绑定命令时,
CanExecute会自动触发界面更新(例如按钮的可用性),无需手动调用。
3.6 使用对话框服务
Prism 提供了 IDialogService 用于显示对话框,解耦 View 和 ViewModel。
3.6.1 注册对话框
在 App.RegisterTypes 中注册对话框:
csharp
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialog<NotificationDialog, NotificationDialogViewModel>();
}
3.6.2 创建对话框 View 和 ViewModel
添加一个用户控件 NotificationDialog.xaml 作为对话框内容:
xml
<UserControl x:Class="WpfDemo.Views.NotificationDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="300" Height="200">
<Grid>
<TextBlock Text="{Binding Message}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</UserControl>
添加 ViewModel NotificationDialogViewModel.cs:
csharp
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
namespace WpfDemo.ViewModels
{
public class NotificationDialogViewModel : BindableBase, IDialogAware
{
private string _message;
public string Message
{
get { return _message; }
set { SetProperty(ref _message, value); }
}
public string Title => "提示";
public event Action<IDialogResult> RequestClose;
public bool CanCloseDialog() => true;
public void OnDialogClosed() { }
public void OnDialogOpened(IDialogParameters parameters)
{
Message = parameters.GetValue<string>("message");
}
}
}
3.6.3 在 ViewModel 中使用对话框
修改 MainWindowViewModel,注入 IDialogService:
csharp
private readonly IDialogService _dialogService;
public MainWindowViewModel(IDialogService dialogService)
{
_dialogService = dialogService;
LoginCommand = new DelegateCommand(ExecuteLogin, CanExecuteLogin);
}
private void ExecuteLogin()
{
if (UserName == "admin" && Password == "123456")
{
_dialogService.ShowDialog("NotificationDialog", new DialogParameters($"message=登录成功"), r => { });
}
else
{
_dialogService.ShowDialog("NotificationDialog", new DialogParameters($"message=用户名或密码错误"), r => { });
}
}
注意事项:
IDialogService通过构造函数注入,由 Prism 容器自动提供。DialogParameters用于传递参数给对话框。
第四部分:注意事项与学习资源
4.1 开发注意事项总结
- 布局优先:在写界面之前,先用布局容器规划好结构,避免绝对定位导致界面缩放问题。
- 命名规范 :为控件起有意义的名字(如
UserNameTextBox),便于维护。 - 资源管理:将样式、模板、转换器等放入资源字典,提高复用性。
- 数据绑定:尽量使用绑定而不是在 code-behind 中直接操作控件。
- 异步处理 :涉及耗时操作(如网络请求)时,使用异步命令(
DelegateCommand支持异步委托)。 - 异常处理:在 ViewModel 中添加异常捕获,避免程序崩溃。
- 性能优化 :虚拟化长列表,减少 UI 元素数量;使用
ObservableCollection时注意不要频繁更新整个集合。 - MVVM 纯度 :避免在 ViewModel 中引用任何 View 类型(如
MessageBox),使用服务代替。
4.2 官方与社区资源
-
Microsoft 官方文档 :WPF .NET 文档 最权威的基础知识来源。
-
Prism 官方文档 :Prism Library 详细介绍了 Prism 的各个模块。
-
ModernWpfUI GitHub :ModernWpfUI 查看源码和示例。
-
视频教程:B 站搜索"WPF 入门"或"Prism 教程",有很多免费视频。
-
书籍推荐:《深入浅出 WPF》(刘铁锰)、《Prism 框架开发实战》。
通过以上一步步的学习,您应该已经掌握了 WPF 的基础开发、ModernUI 的集成以及 MVVM/Prism 的核心用法。继续动手实践,多写多练,您将能构建出专业、现代化的桌面应用程序。