欢迎光临
我们一直在努力

WPF 从入门到实践:基础、ModernUI 与 MVVM 完全指南

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,您会看到类似下面的代码:

    <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:

    <Grid>
    <TextBlock Text="欢迎学习WPF"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    FontSize="20"
    Foreground="Blue"/>

    </Grid>

    注意事项:

    • HorizontalAlignment 和 VerticalAlignment 用于控制控件在容器内的对齐方式。
    • 属性值可以直接写在标签内,也可以使用属性元素语法(复杂对象时使用)。
    • 所有 XAML 元素都必须正确关闭(自关闭或成对关闭)。
    2.2 添加一个按钮(Button)并处理点击事件

    在 Grid 中添加一个按钮,并为其添加点击事件:

    <Button Content="点我"
    Width="100" Height="30"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Click="Button_Click"/>

    然后按 F12 或右键点击 Click="Button_Click" 选择“转到定义”,Visual Studio 会自动在 MainWindow.xaml.cs 中生成事件处理程序:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
    MessageBox.Show("按钮被点击了!");
    }

    注意事项:

    • 事件名称可以任意,但通常采用 控件名_事件名 的命名方式。
    • 在 XAML 中写 Click="Button_Click" 后,编译时会自动检查后台是否有匹配的方法,如果没有会报错。
    • 事件处理程序的方法签名必须匹配委托定义(通常是 object sender, RoutedEventArgs e)。
    2.3 文本框(TextBox)和密码框(PasswordBox)

    添加一个文本框和一个密码框,并在按钮点击时获取它们的值。

    <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>

    后台代码:

    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 并绑定数据:

    <ListBox x:Name="FruitListBox" Width="200" Height="100" Margin="5" DisplayMemberPath="Name"/>

    在窗口加载时填充数据(MainWindow 构造函数中):

    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:

    <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:表格布局,可定义行和列。<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 中添加一个滑块和一个文本块,使文本块显示滑块的当前值:

    <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 或窗口资源中定义样式。

    <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:

    <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:

    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,引入主题资源

    <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:

    <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 中添加主题管理器资源:

    <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:

    <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:

    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:

    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 设计时支持,实际运行时由容器注入):

    <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:

    <PasswordBox x:Name="PasswordBox" Grid.Row="1" Grid.Column="1" Margin="5"/>

    修改 LoginCommand 执行时获取密码:

    private void ExecuteLogin()
    {
    // 如何获取密码?可以在 View 中调用 ViewModel 的方法,但会破坏解耦。
    // 最佳实践:使用 Prism 的 Interaction 或 Behavior,或者使用附加属性。
    // 简单起见,我们可以在 View 的 code-behind 中处理按钮点击,并调用 ViewModel 的方法。
    }

    为了保持纯净的 MVVM,我们使用 Prism 的 PasswordBoxHelper(需要安装 Prism.Wpf 包):

    在 XAML 中添加命名空间:

    xmlns:prism="http://prismlibrary.com/"

    为 PasswordBox 添加附加属性:

    <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 中注册对话框:

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {
    containerRegistry.RegisterDialog<NotificationDialog, NotificationDialogViewModel>();
    }

    3.6.2 创建对话框 View 和 ViewModel

    添加一个用户控件 NotificationDialog.xaml 作为对话框内容:

    <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:

    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:

    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 的核心用法。继续动手实践,多写多练,您将能构建出专业、现代化的桌面应用程序。

    赞(0)
    未经允许不得转载:171主机测评 » WPF 从入门到实践:基础、ModernUI 与 MVVM 完全指南
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址