WPF中Image控件绑定到自定义类属性
首先我们定义一个Student类,有ID,Name,Photo(保存图片路径).
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BindingImage { public class Student { public int Id { get; set; } public string Name { get; set; } public string Photo { get; set; } } }
然后我们写两个有关数据库操作的类,SqlHelper,StudentDAL,因为我们不希望在UI层后台的代码中出现有关数据库的操作,我们定义了这两个类。
上代码:
SqlHelper:
1 using System; 2 using System.Collections.Generic; 3 using System.Configuration; 4 using System.Data; 5 using System.Data.SqlClient; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 10 namespace BindingImage 11 { 12 public static class SqlHelper 13 { 14 //读取保存在APP.config的链接字符串 15 public static readonly string connstr = 16 ConfigurationManager.ConnectionStrings["connstr"].ConnectionString; 17 18 //执行ExcuteNonQuery方法,返回受影响的行数 19 public static int ExecuteNonQuery(string sql, 20 params SqlParameter[] parameters) 21 { 22 using (SqlConnection conn = new SqlConnection(connstr)) 23 { 24 conn.Open(); 25 using (SqlCommand cmd = conn.CreateCommand()) 26 { 27 cmd.CommandText = sql; 28 cmd.Parameters.AddRange(parameters); 29 return cmd.ExecuteNonQuery(); 30 } 31 } 32 } 33 //返回DataTable结果集 34 public static DataTable ExecuteDataTable(string sql, 35 params SqlParameter[] parameters) 36 { 37 using (SqlConnection conn = new SqlConnection(connstr)) 38 { 39 conn.Open(); 40 using (SqlCommand cmd = conn.CreateCommand()) 41 { 42 cmd.CommandText = sql; 43 cmd.Parameters.AddRange(parameters); 44 45 DataSet dataset = new DataSet(); 46 SqlDataAdapter adapter = new SqlDataAdapter(cmd); 47 adapter.Fill(dataset); 48 return dataset.Tables[0]; 49 } 50 } 51 } 52 //若数据库中的字段值为Null 53 public static object FromDbValue(object value) 54 { 55 if (value == DBNull.Value) 56 { 57 return null; 58 } 59 else 60 { 61 return value; 62 } 63 } 64 65 //若实体类重的属性值为null 66 public static object ToDbValue(object value) 67 { 68 if (value == null) 69 { 70 return DBNull.Value; 71 } 72 else 73 { 74 return value; 75 } 76 } 77 } 78 79 80 }
StudentDAL:
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Data.SqlClient; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace BindingImage 10 { 11 public static class StudentDAL 12 { 13 14 public static Student GetById(int id) 15 { 16 DataTable table = SqlHelper.ExecuteDataTable("select * from T_Student2 where Id=@Id", 17 new SqlParameter("@Id", id)); 18 if (table.Rows.Count <= 0) 19 { 20 return null; 21 } 22 else if (table.Rows.Count > 1) 23 { 24 throw new Exception("存在Id重复用户!"); 25 } 26 else 27 { 28 return ToStudent(table.Rows[0]); 29 } 30 } 31 32 public static void Update(Student st) 33 { 34 SqlHelper.ExecuteNonQuery("update T_Student2 set Name=@Name,Photo=@Photo where Id=@Id", 35 new SqlParameter("@Name", SqlHelper.ToDbValue( st.Name)), 36 new SqlParameter("@Photo", SqlHelper.ToDbValue( st.Photo)), 37 new SqlParameter("@Id",st.Id)); 38 39 } 40 41 private static Student ToStudent(DataRow row) 42 { 43 Student st = new Student(); 44 st.Id = (int)row["Id"]; 45 st.Name =(string)SqlHelper.FromDbValue(row["Name"]); 46 st.Photo = (string)SqlHelper.FromDbValue(row["Photo"]); 47 return st; 48 } 49 } 50 }
UI层:
在学生ID文本框中输入Id,然后显示在此界面中,我们将学生姓名 学生头像保定到相应控件元素上,XAML代码如下
1 <Window x:Class="BindingImage.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:local="clr-namespace:BindingImage" 5 Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" WindowStartupLocation="CenterScreen"> 6 <Window.Resources> 7 <local:Converter x:Key="con"/> 8 </Window.Resources> 9 <Grid Name="gridstudent"> 10 <TextBox x:Name="txtId" HorizontalAlignment="Left" Height="23" Margin="66,33,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> 11 <TextBox x:Name="txtName" HorizontalAlignment="Left" Height="23" Margin="66,105,0,0" TextWrapping="Wrap" Text="{Binding Name}" VerticalAlignment="Top" Width="120"/> 12 <Image x:Name="imgPhoto" Source="{Binding Photo,Converter={StaticResource con}}" HorizontalAlignment="Left" Height="100" Margin="271,105,0,0" VerticalAlignment="Top" Width="100"/> 13 <Button Content="Save" HorizontalAlignment="Left" Margin="126,259,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/> 14 <Button Content="LoadPhoto" HorizontalAlignment="Left" Margin="405,186,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> 15 <Button Content="Cancel" HorizontalAlignment="Left" Margin="282,259,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2"/> 16 <TextBlock HorizontalAlignment="Left" Margin="11,41,0,0" TextWrapping="Wrap" Text="学生ID:" VerticalAlignment="Top" RenderTransformOrigin="-0.159,1.145"/> 17 <TextBlock HorizontalAlignment="Left" Margin="15,113,0,0" TextWrapping="Wrap" Text="学生姓名:" VerticalAlignment="Top" RenderTransformOrigin="-0.159,1.145"/> 18 <TextBlock HorizontalAlignment="Left" Margin="204,113,0,0" TextWrapping="Wrap" Text="学生头像:" VerticalAlignment="Top" RenderTransformOrigin="-0.159,1.145"/> 19 <Button Content="显示" HorizontalAlignment="Left" Margin="204,33,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_3"/> 20 </Grid> 21 </Window>
然后做最为关键的一步,对数据类型的转换,我们需要把Student类中的Photo属性也就是图片路径转换为BitmapImage类型,才能显示在UI上。
Converter:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows.Data; 7 using System.Windows.Media; 8 using System.Windows.Media.Imaging; 9 10 namespace BindingImage 11 { 12 public class Converter:IValueConverter 13 { 14 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 15 { 16 //若数据库中字段为空,返回默认值 17 if (value == null) 18 { 19 return new BitmapImage(new Uri(@"D:\1.jpg")); 20 } 21 return new BitmapImage(new Uri(value.ToString())); 22 23 } 24 25 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 26 { 27 28 //图片是不能编辑的,这里就没有必要支持反向转换 29 throw new NotImplementedException(); 30 } 31 } 32 }
剩下的是操作的一些逻辑代码
1 using Microsoft.Win32; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using System.Windows; 8 using System.Windows.Controls; 9 using System.Windows.Data; 10 using System.Windows.Documents; 11 using System.Windows.Input; 12 using System.Windows.Media; 13 using System.Windows.Media.Imaging; 14 using System.Windows.Navigation; 15 using System.Windows.Shapes; 16 17 namespace BindingImage 18 { 19 /// <summary> 20 /// Interaction logic for MainWindow.xaml 21 /// </summary> 22 public partial class MainWindow : Window 23 { 24 public MainWindow() 25 { 26 InitializeComponent(); 27 } 28 29 private void Window_Loaded(object sender, RoutedEventArgs e) 30 { 31 32 } 33 private void LoadData() 34 { 35 36 this.gridstudent.DataContext = StudentDAL.GetById(Convert.ToInt32(txtId.Text)); 37 38 } 39 40 private void Button_Click(object sender, RoutedEventArgs e) 41 { 42 OpenFileDialog ofd = new OpenFileDialog(); 43 ofd.Filter = "JPG图片|*.jpg|PNGt图片|*.png"; 44 if (ofd.ShowDialog() == true) 45 { 46 47 string filename = ofd.FileName; 48 imgPhoto.Source = new BitmapImage(new Uri(filename)); 49 Student student = (Student)this.gridstudent.DataContext; 50 student.Photo = filename; 51 } 52 } 53 54 private void Button_Click_1(object sender, RoutedEventArgs e) 55 { 56 Student student = (Student)this.gridstudent.DataContext; 57 StudentDAL.Update(student); 58 if (MessageBox.Show("保存完毕", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK) 59 { 60 61 this.Close(); 62 } 63 } 64 65 private void Button_Click_2(object sender, RoutedEventArgs e) 66 { 67 this.Close(); 68 } 69 70 private void Button_Click_3(object sender, RoutedEventArgs e) 71 { 72 if (txtId.Text == "") 73 { 74 return; 75 } 76 LoadData(); 77 78 } 79 80 } 81 }
希望对大家对WPF中的绑定知识有所启迪,尤其是数据转换这方面,因为常规的一些数据转换,.NET已经报我们做好,就是这些类似于图片Source属性,CheckBox控件IsChecked属性和我们定义的类属性的转换等等.