如何在C#的WPF/Windows Store应用中通过WebService读写SQL Server图片
实现WPF/Windows Store通过Web服务检索SQL Server图片并显示到Image控件
我来帮你完善这个从SQL Server取图片、通过Web服务传输,最终在WPF/Windows Store应用的Image控件显示的完整流程。你的现有代码已经有了开头,我们把它补全并优化,同时覆盖客户端的实现。
一、Web服务端完善
首先你需要定义一个Customer实体类,用来封装返回给客户端的数据——这里我们把图片转换成Base64字符串(相比直接传二进制,Base64在Web服务中更易处理):
public class Customer { public int ID { get; set; } public string PictureBase64 { get; set; } // 用Base64格式存储图片数据 public string Customer_Name { get; set; } public string Contact_No { get; set; } public DateTime Time_In { get; set; } }
然后补全你的Web服务方法,处理数据库查询和图片转换:
[WebMethod] public List<Customer> GetRecentUnsoldCustomers() { List<Customer> customerList = new List<Customer>(); Connection con = new Connection(); try { con.Start(); // 保留你的原查询逻辑,注意Date字段需为日期类型 string query = @"Select ID,Picture, Customer_Name, Contact_No, Time_In from Customers_Data WHERE ( Date >= dateadd(day,datediff(day,7,GETDATE()),0) AND Date < dateadd(day,datediff(day,0,GETDATE()),1)) And (Sale_Made='No')"; DataTable dt = con.Select(query); foreach(DataRow row in dt.Rows) { Customer customer = new Customer(); customer.ID = Convert.ToInt32(row["ID"]); customer.Customer_Name = row["Customer_Name"].ToString(); customer.Contact_No = row["Contact_No"].ToString(); customer.Time_In = Convert.ToDateTime(row["Time_In"]); // 处理数据库中的二进制图片,转为Base64 if(row["Picture"] != DBNull.Value) { byte[] imageBytes = (byte[])row["Picture"]; customer.PictureBase64 = Convert.ToBase64String(imageBytes); } customerList.Add(customer); } } catch(Exception ex) { // 建议添加日志记录,这里直接抛出便于客户端排查 throw new Exception("获取客户数据失败: " + ex.Message); } finally { con.Stop(); } return customerList; }
二、WPF客户端实现
1. XAML布局
先在XAML里定义显示客户列表和图片的UI:
<Window x:Class="WpfImageDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="未成交客户列表" Height="450" Width="800"> <Grid> <ListBox x:Name="CustomerList" Margin="10"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" Padding="5"> <!-- 显示图片 --> <Image Width="120" Height="120" Source="{Binding CustomerImage}" Stretch="UniformToFill" Margin="0,0,10,0"/> <!-- 显示客户信息 --> <StackPanel> <TextBlock Text="{Binding Customer_Name}" FontSize="16" FontWeight="Bold"/> <TextBlock Text="{Binding Contact_No}" Margin="0,2,0,0"/> <TextBlock Text="{Binding Time_In, StringFormat='到店时间: {0:yyyy/MM/dd HH:mm}'}" Margin="0,2,0,0" Foreground="Gray"/> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </Window>
2. 代码后台处理
添加Web服务引用后,在代码后台获取数据并把Base64转成WPF能识别的BitmapImage:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows; using System.Windows.Media.Imaging; // 替换成你的Web服务引用命名空间 using WpfImageDemo.MyWebService; namespace WpfImageDemo { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // 异步加载数据,避免阻塞UI LoadCustomerDataAsync(); } private async void LoadCustomerDataAsync() { try { // 实例化Web服务代理 using(var client = new Service1SoapClient()) { List<Customer> customers = await client.GetRecentUnsoldCustomersAsync(); // 转换为本地ViewModel,方便绑定图片 var viewModels = customers.Select(c => new CustomerViewModel { Customer_Name = c.Customer_Name, Contact_No = c.Contact_No, Time_In = c.Time_In, CustomerImage = ConvertBase64ToBitmapImage(c.PictureBase64) }).ToList(); CustomerList.ItemsSource = viewModels; } } catch(Exception ex) { MessageBox.Show($"加载数据失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } // 将Base64字符串转为BitmapImage private BitmapImage ConvertBase64ToBitmapImage(string base64String) { if(string.IsNullOrEmpty(base64String)) return null; byte[] imageBytes = Convert.FromBase64String(base64String); using(var ms = new MemoryStream(imageBytes)) { BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.CacheOption = BitmapCacheOption.OnLoad; // 确保流关闭后图片仍可用 bitmap.StreamSource = ms; bitmap.EndInit(); return bitmap; } } } // 本地ViewModel类,用于UI绑定 public class CustomerViewModel { public string Customer_Name { get; set; } public string Contact_No { get; set; } public DateTime Time_In { get; set; } public BitmapImage CustomerImage { get; set; } } }
三、Windows Store应用客户端实现
Windows Store应用的逻辑和WPF类似,只是图片转换的API略有不同:
1. 图片转换方法
private async Task<BitmapImage> ConvertBase64ToBitmapImageAsync(string base64String) { if(string.IsNullOrEmpty(base64String)) return null; byte[] imageBytes = Convert.FromBase64String(base64String); using(var ms = new InMemoryRandomAccessStream()) { await ms.WriteAsync(imageBytes.AsBuffer()); ms.Seek(0); BitmapImage image = new BitmapImage(); await image.SetSourceAsync(ms); return image; } }
2. 数据加载逻辑
private async void Page_Loaded(object sender, RoutedEventArgs e) { try { using(var client = new MyWebService.Service1SoapClient()) { var customers = await client.GetRecentUnsoldCustomersAsync(); var viewModels = new ObservableCollection<CustomerViewModel>(); foreach(var c in customers) { viewModels.Add(new CustomerViewModel { Customer_Name = c.Customer_Name, Contact_No = c.Contact_No, Time_In = c.Time_In, CustomerImage = await ConvertBase64ToBitmapImageAsync(c.PictureBase64) }); } CustomerListView.ItemsSource = viewModels; } } catch(Exception ex) { await new MessageDialog($"加载失败: {ex.Message}").ShowAsync(); } }
四、关键注意事项
- 数据库字段类型:确保SQL Server中
Picture字段是varbinary(max)类型,适合存储图片二进制数据。 - 性能优化:如果图片较大,建议先压缩图片再存储/传输,Base64会比原二进制大33%左右,大图片可能影响传输速度。
- 异步处理:客户端一定要用异步方法调用Web服务,避免UI线程阻塞导致应用假死。
- 异常处理:在Web服务和客户端都要添加完善的异常捕获,方便排查问题。
- Windows Store权限:在Package.appxmanifest中开启
Internet (Client)权限,确保应用能访问Web服务。
内容的提问来源于stack exchange,提问作者shahzad_Ali
相关产品推荐
相关产品推荐

