WPF基础知识(八)

六、WPF 与数据库交互

6.1 使用 ADO.NET 访问数据库

6.1.1 连接数据库

以 SQL Server 数据库为例,使用 ADO.NET 连接数据库:

using System.Data.SqlClient;

string connectionString = "Data Source=YOUR_SERVER;Initial Catalog=YOUR_DATABASE;User ID=YOUR_USER;Password=YOUR_PASSWORD";
using (SqlConnection connection = new SqlConnection(connectionString))
{
    try
    {
        connection.Open();
        Console.WriteLine("Connected to the database.");
    }
    catch (SqlException ex)
    {
        Console.WriteLine("Error: " + ex.Message);
    }
}
6.1.2 执行查询操作

执行 SQL 查询并获取结果:

string query = "SELECT * FROM Customers";
using (SqlCommand command = new SqlCommand(query, connection))
{
    SqlDataReader reader = command.ExecuteReader();
    while (reader.Read())
    {
        string customerName = reader["CustomerName"].ToString();
        string email = reader["Email"].ToString();
        Console.WriteLine($"Name: {customerName}, Email: {email}");
    }
    reader.Close();
}
6.1.3 执行插入、更新和删除操作

执行插入操作:

string insertQuery = "INSERT INTO Customers (CustomerName, Email) VALUES (@Name, @Email)";
using (SqlCommand command = new SqlCommand(insertQuery, connection))
{
    command.Parameters.AddWithValue("@Name", "New Customer");
    command.Parameters.AddWithValue("@Email", "newcustomer@example.com");
    int rowsAffected = command.ExecuteNonQuery();
    Console.WriteLine($"{rowsAffected} rows inserted.");
}

更新和删除操作类似,只需修改 SQL 语句和参数。

6.2 使用 Entity Framework 进行数据访问

6.2.1 安装 Entity Framework

在 Visual Studio 中,通过 NuGet 包管理器安装 Microsoft.EntityFrameworkCore.SqlServer 包。

6.2.2 创建数据模型和 DbContext

创建一个 Customer 类作为数据模型:

public class Customer
{
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }
    public string Email { get; set; }
}

创建一个 DbContext 类:

using Microsoft.EntityFrameworkCore;

public class CustomerContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Data Source=YOUR_SERVER;Initial Catalog=YOUR_DATABASE;User ID=YOUR_USER;Password=YOUR_PASSWORD");
    }
}
6.2.3 进行数据操作

使用 CustomerContext 进行数据查询、插入、更新和删除操作:

using (CustomerContext context = new CustomerContext())
{
    // 查询数据
    var customers = context.Customers.ToList();
    foreach (var customer in customers)
    {
        Console.WriteLine($"Name: {customer.CustomerName}, Email: {customer.Email}");
    }

    // 插入数据
    Customer newCustomer = new Customer { CustomerName = "Another Customer", Email = "another@example.com" };
    context.Customers.Add(newCustomer);
    context.SaveChanges();

    // 更新数据
    var customerToUpdate = context.Customers.Find(1);
    if (customerToUpdate != null)
    {
        customerToUpdate.Email = "updated@example.com";
        context.SaveChanges();
    }

    // 删除数据
    var customerToDelete = context.Customers.Find(2);
    if (customerToDelete != null)
    {
        context.Customers.Remove(customerToDelete);
        context.SaveChanges();
    }
}

七、WPF 应用程序的部署

7.1 发布配置

在 Visual Studio 中,右键单击项目,选择 “发布”。在发布向导中,进行以下配置:

  • 目标位置:指定应用程序发布的位置,可以是本地文件夹、网络共享或远程服务器。
  • 发布模式
    • 框架依赖:应用程序依赖于系统中已安装的.NET 运行时,发布包体积较小,但需要确保目标系统安装了相应的运行时。
    • 独立:应用程序包含了所有必要的.NET 运行时组件,无需在目标系统上安装额外的运行时,但发布包体积较大。
  • 目标运行时:选择目标系统的操作系统和架构,如 win-x64win-x86 等。

7.2 创建安装程序

7.2.1 使用 Inno Setup
  • 下载和安装:从 Inno Setup 官方网站下载并安装该工具。
  • 创建脚本:编写一个 .iss 脚本文件,定义安装程序的各种设置,如安装目录、文件复制、快捷方式创建等。以下是一个简单的示例:
[Setup]
AppName=MyWpfApp
AppVersion=1.0
DefaultDirName={pf}\MyWpfApp
OutputDir=.\Output
OutputBaseFilename=MyWpfAppSetup

[Files]
Source: "path\to\your\app\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs

[Icons]
Name: "{group}\MyWpfApp"; Filename: "{app}\MyWpfApp.exe"

  • 编译脚本:打开 Inno Setup 编译器,加载 .iss 脚本文件,点击编译按钮生成安装程序。
7.2.2 使用 WiX Toolset
  • 安装:从 WiX Toolset 官方网站下载并安装该工具。
  • 创建 XML 配置文件:编写一个 .wxs 文件,使用 WiX 的 XML 语法定义安装程序的结构和行为。例如:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" Name="MyWpfApp" Language="1033" Version="1.0.0" Manufacturer="MyCompany" UpgradeCode="PUT-GUID-HERE">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

        <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
        <MediaTemplate />

        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLFOLDER" Name="MyWpfApp" />
            </Directory>
        </Directory>

        <DirectoryRef Id="INSTALLFOLDER">
            <Component Id="ProductComponent" Guid="PUT-GUID-HERE">
                <File Source="path\to\your\app\MyWpfApp.exe" />
            </Component>
        </DirectoryRef>

        <Feature Id="ProductFeature" Title="MyWpfApp" Level="1">
            <ComponentRef Id="ProductComponent" />
        </Feature>
    </Product>
</Wix>

  • 编译和链接:使用 WiX 工具集的命令行工具(如 candle.exe 和 light.exe)编译和链接 .wxs 文件,生成安装程序。

7.3 部署注意事项

  • 运行时依赖:如果选择框架依赖的发布模式,确保目标系统安装了相应的.NET 运行时。可以提供运行时安装包的下载链接,或者在安装程序中集成运行时的安装步骤。
  • 权限问题:确保应用程序在目标系统上有足够的权限来运行,特别是在访问文件系统、网络等资源时。
  • 版本更新:考虑实现应用程序的版本更新机制,方便用户及时获取最新版本的功能和修复。可以使用第三方库或自行实现检查更新和下载更新的逻辑。

八、WPF 应用的性能优化与调试

8.1 性能优化

8.1.1 布局优化
  • 减少布局嵌套:复杂的布局嵌套会增加布局计算的开销,尽量简化布局结构。例如,避免过多的 Grid 嵌套,可以使用 StackPanel 或 WrapPanel 进行简单的排列。
  • 使用虚拟化面板:对于列表控件,如 ListView 和 DataGrid,使用 VirtualizingStackPanel 可以提高性能。当列表项数量较多时,VirtualizingStackPanel 只渲染当前可见的项,减少内存占用。
<ListView ItemsSource="{Binding Items}">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>
8.1.2 资源管理
  • 图片优化:使用合适的图片格式和分辨率,避免使用过大的图片。可以使用图像压缩工具对图片进行压缩,减少内存占用。同时,使用 BitmapCache 对不经常变化的图片进行缓存,提高渲染性能。
<Image Source="image.jpg">
    <Image.CacheMode>
        <BitmapCache />
    </Image.CacheMode>
</Image>

  • 资源回收:及时释放不再使用的资源,如关闭数据库连接、释放非托管资源等。在 Dispose 方法中实现资源的释放逻辑,确保资源被正确回收。
8.1.3 异步操作

对于耗时的操作,如网络请求、数据库查询等,使用异步编程模型,避免阻塞 UI 线程,提高应用程序的响应性。例如,使用 async 和 await 关键字:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    await Task.Run(() =>
    {
        // 模拟耗时操作
        Thread.Sleep(3000);
    });
    // 更新 UI
    MessageBox.Show("Operation completed.");
}

8.2 调试技巧

8.2.1 断点调试

在代码中设置断点是最常用的调试方法。可以在代码隐藏文件或 ViewModel 中设置断点,当程序执行到断点处时会暂停,方便查看变量的值和程序的执行流程。在 Visual Studio 中,只需在代码行号旁边单击即可设置断点。

8.2.2 输出调试信息

使用 Debug.WriteLine 方法在调试窗口输出调试信息,帮助跟踪程序的执行过程。例如:

Debug.WriteLine("Entering method: " + MethodBase.GetCurrentMethod().Name);
8.2.3 可视化调试工具

Visual Studio 提供了一些可视化调试工具,如实时可视化树和实时属性资源管理器。通过这些工具可以查看 UI 元素的层次结构和属性值,帮助定位布局和样式问题。在调试时,选择 “调试” -> “窗口” -> “实时可视化树” 或 “实时属性资源管理器” 即可打开相应的工具窗口。

九、WPF 与第三方技术集成

9.1 与 Web 技术集成

9.1.1 使用 WebBrowser 控件

WebBrowser 控件可以在 WPF 应用中嵌入网页。例如,在窗口中显示一个网页:

<WebBrowser Source="https://www.example.com" />

可以通过 Navigate 方法动态加载不同的网页:

private void Button_Click(object sender, RoutedEventArgs e)
{
    webBrowser.Navigate("https://www.google.com");
}