六、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-x64
、win-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");
}