Silverlight:双向绑定综合应用-自动更新集合汇总字段

Silverlight:双向绑定综合应用-自动更新集合汇总字段,第1张

概述场景:有一家公司(类名:Company),它有N多员工(类名:Employee)。要在界面上用网格显示所有员工的姓名、工资,并且当 *** 作用户在网格里对员工进行增减或修改其工资时,能自动汇总出员工工资的总和并显示出来。 员工类 Employee代码如下: View Code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 场景:有一家公司(类名:Company),它有N多员工(类名:Employee)。要在界面上用网格显示所有员工的姓名、工资,并且当 *** 作用户在网格里对员工进行增减或修改其工资时,能自动汇总出员工工资的总和并显示出来。 员工类 Employee代码如下: View Code ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 /// <summary> /// 员工类 /// </summary> public class Employee:INotifyPropertyChanged {   private string _name = ""; public string name { set { _name = value; OnPropertyChanged("name"); } get { return _name; } }   private int _salary = 0;   public int Salary { get { return _salary; } set { _salary = value; OnPropertyChanged("Salary"); } }     public event PropertyChangedEventHandler PropertyChanged;   protected voID OnPropertyChanged(string propertyname) { if (PropertyChanged != null) { PropertyChanged(this,new PropertyChangedEventArgs(propertyname)); } } }
公司类 Company代码原型如下: View Code ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class Company {   private ObservableCollection<Employee> _employeeCollection = new ObservableCollection<Employee>();   /// <summary> /// 公司的"员工集合" /// </summary> public ObservableCollection<Employee> EmployeeCollection { get { return _employeeCollection; }   }       private voID computeSalaryTotal() { _salaryTotal = _employeeCollection.Sum(c => c.Salary);   }   private int _salaryTotal = 0;       /// <summary> /// 工资汇总 /// </summary> public int SalaryTotal { get { computeSalaryTotal(); return _salaryTotal; } }     }

常规解决办法: 可以在GrID每行“工资”字段对应的TextBox上,注册TextChanged或LostFocus事件,在输入值变化或失去焦点时,去更新总和。 这是很容易想到的办法,但是并不优雅,原因: 1、每行的TextBox上都要去绑定事件,并在xaml.cs上写代码处理类似 TextBoxTotal.text = company.SalaryTotal 的逻辑。这样界面逻辑代码与UI绑得太紧,应对变化的能力有限。比如以后将TextBox换成其它形式的控件,一旦并不支持TextChanged事件,原来的代码就得修改。 2、代码重用率低,如果其它界面上也需要类似的需求,只能把本页面Xaml、Xaml.cs的代码复制一遍,如果以后需求有变化,更增加了维护成本。 所以,理想的解决方法,应该是Company类自身能“智能感知”员工的变化,并自动更新工资汇总字段。(即:员工Employee的工资有变化时,应该主动通知Company类。这跟实际公司的运营管理也比较接近,人事给员工调整了工资,肯定会主动通知财务,所以财务肯定也就知道了最新的工资汇总数据。) 这时,双向绑定就再一次体现了这种威力,我们把Company类改造一下: View Code ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 @H_502_889@ 82 83 84 85 86 87 public class Company:INotifyPropertyChanged {   private ObservableCollection<Employee> _employeeCollection = new ObservableCollection<Employee>();   /// <summary> /// 公司的"员工集合" /// </summary> public ObservableCollection<Employee> EmployeeCollection { get { return _employeeCollection; }   }   /// <summary> /// 构造函数 /// </summary> public Company() { _employeeCollection.CollectionChanged += new NotifyCollectionChangedEventHandler(_employeeCollection_CollectionChanged); }   /// <summary> /// 员工有“增减”时自动触发 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private voID _employeeCollection_CollectionChanged(object sender,NotifyCollectionChangedEventArgs e) { //重新计算工资总和 computeSalaryTotal();   //每个员工的“工资”属性变化时,自动触发指定事件 foreach (var item in _employeeCollection) {   item.PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged); item.PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);   } }   /// <summary> /// 员工属性变化时自动调用本方法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private voID item_PropertyChanged(object sender,PropertyChangedEventArgs e) { //如果是"工资"属性变化,则自动重新计算工资汇总 if (e.Propertyname == "Salary") { computeSalaryTotal(); } }   private voID computeSalaryTotal() { _salaryTotal = _employeeCollection.Sum(c => c.Salary); OnPropertyChanged("SalaryTotal");//工资总合重新计算后,向外广播事件,以便UI能自动更新 }   private int _salaryTotal = 0;       /// <summary> /// 工资汇总 /// </summary> public int SalaryTotal { get { return _salaryTotal; } }   private voID OnPropertyChanged(string propertyname) { if (PropertyChanged != null) { PropertyChanged(this,new PropertyChangedEventArgs(propertyname)); @H_502_889@ } }     public event PropertyChangedEventHandler PropertyChanged; }
这里,我们充分利用了INotifyPropertyChanged接口的PropertyChanged事件,以及INotifyCollectionChanged接口的CollectionChanged事件,实现了自动通知。 这样一来,界面UI部分就轻松多了,只需要简单的绑定即可。
Xaml部分: View Code ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 <UserControl x:Class="XmlClassSerelizer.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWIDth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">   <StackPanel x:name="LayoutRoot" Background="White"> <sdk:DataGrID autoGenerateColumns="False" HorizontalAlignment="Center" margin="0,10,0" name="dataGrID1" VerticalAlignment="Center"   ItemsSource="{Binding EmployeeCollection}"> <sdk:DataGrID.Columns> <sdk:DataGrIDTemplateColumn header="姓名"> <sdk:DataGrIDTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding name,Mode=TwoWay}" VerticalAlignment="Center" margin="1"></TextBox> </DataTemplate> </sdk:DataGrIDTemplateColumn.CellTemplate> </sdk:DataGrIDTemplateColumn>   <sdk:DataGrIDTemplateColumn header="工资"> <sdk:DataGrIDTemplateColumn.CellTemplate> <DataTemplate> <TextBox Text="{Binding Salary,Mode=TwoWay}" VerticalAlignment="Center" margin="1"></TextBox> </DataTemplate> </sdk:DataGrIDTemplateColumn.CellTemplate> </sdk:DataGrIDTemplateColumn>     <sdk:DataGrIDTemplateColumn header=" *** 作"> <sdk:DataGrIDTemplateColumn.CellTemplate> <DataTemplate> <button Click="RemoveEmployee" HorizontalAlignment="Center" VerticalAlignment="Center" padding="10,1">-</button> </DataTemplate> </sdk:DataGrIDTemplateColumn.CellTemplate> </sdk:DataGrIDTemplateColumn> </sdk:DataGrID.Columns> </sdk:DataGrID>   <StackPanel HorizontalAlignment="Center" OrIEntation="Horizontal" margin="5"> <TextBlock VerticalAlignment="Center">工资总合:</TextBlock> <TextBlock Text="{Binding SalaryTotal,Mode=TwoWay}" margin="5,5,0" WIDth="60"></TextBlock>   </StackPanel>   <StackPanel HorizontalAlignment="Center" OrIEntation="Horizontal" margin="5">   <button Click="AddEmployee" padding="10,1">+</button> </StackPanel> </StackPanel> </UserControl>
Xaml.cs部分: View Code ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 using System.windows; using System.windows.Controls;   namespace XmlClassSerelizer { public partial class MainPage : UserControl { Company c = new Company();   public MainPage() { InitializeComponent(); this.Loaded += new RoutedEventHandler(MainPage_Loaded); }   voID MainPage_Loaded(object sender,RoutedEventArgs e) {     Employee e1 = new Employee(){ name="张三",Salary=3000}; Employee e2 = new Employee(){ name="李四",Salary=4000}; c.EmployeeCollection.Add(e1); c.EmployeeCollection.Add(e2);   this.DataContext = c;   }     /// <summary> /// 删除员工 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private voID RemoveEmployee(object sender,RoutedEventArgs e) { var emp = (sender as button).DataContext as Employee; if (emp != null) { c.EmployeeCollection.Remove(emp); } }     /// <summary> /// 添加员工 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private voID AddEmployee(object sender,RoutedEventArgs e) { c.EmployeeCollection.Add(new Employee() { name = "新人",Salary = 1000 }); }     } }
运行效果:

http://www.cnblogs.com/yjmyzz/archive/2011/06/26/2090538.html

总结

以上是内存溢出为你收集整理的Silverlight:双向绑定综合应用-自动更新集合汇总字段全部内容,希望文章能够帮你解决Silverlight:双向绑定综合应用-自动更新集合汇总字段所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1071067.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)

    保存