Silverlight实现DataGrid的Select All功能

 

今天要实现一个DataGrid的Select All功能。查了一下,多是用EventHandler完成的,看起来觉得有点乱,所以自己写了一个。

 

 

代码很简单

 

Xaml
 
   
1 < UserControl x:Class ="SilverlightApp.SelectAllAndOrder.SelectAllPage"
2 xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
6 xmlns:Primitives ="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
7 mc:Ignorable ="d"
8 d:DesignHeight ="500" d:DesignWidth ="400" xmlns:sdk ="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" >
9
10 < UserControl.Resources >
11 < ResourceDictionary >
12 < Style x:Key ="SelectAllTemplate" TargetType ="Primitives:DataGridColumnHeader" >
13 < Setter Property ="ContentTemplate" >
14 < Setter.Value >
15 < DataTemplate >
16 < CheckBox IsChecked =" {Binding DataContext.IsSelectAll,Mode=TwoWay,ElementName=LayoutRoot} " />
17 </ DataTemplate >
18 </ Setter.Value >
19 </ Setter >
20 </ Style >
21 < DataTemplate x:Key ="CheckBoxColumn" >
22 < CheckBox IsChecked =" {Binding IsSelected, Mode=TwoWay} " />
23 </ DataTemplate >
24 </ ResourceDictionary >
25 </ UserControl.Resources >
26
27 < Grid x:Name ="LayoutRoot" Margin ="15" Background ="White" >
28 < Grid.RowDefinitions >
29 < RowDefinition Height ="400" />
30 < RowDefinition Height ="Auto" />
31 </ Grid.RowDefinitions >
32
33 < sdk:DataGrid ItemsSource =" {Binding Users} " AutoGenerateColumns ="False" IsReadOnly ="True" RowHeight ="25" CanUserReorderColumns ="False" >
34 < sdk:DataGrid.Columns >
35 < sdk:DataGridTemplateColumn Width ="55" HeaderStyle =" {StaticResource SelectAllTemplate} "
36 CellTemplate =" {StaticResource CheckBoxColumn} " ></ sdk:DataGridTemplateColumn >
37 < sdk:DataGridTextColumn Width ="120" Header ="姓名" Binding =" {Binding Name} " />
38 </ sdk:DataGrid.Columns >
39 </ sdk:DataGrid >
40
41 < StackPanel Orientation ="Horizontal" Grid.Row ="1" >
42 < Button Content ="Add One Column" Click ="AddColumn" />
43 < Button Margin ="10,0" Content ="Delete One Column" Click ="DeleteColumn" />
44 </ StackPanel >
45 </ Grid >
46   </ UserControl >
47  

 

 

本来打算在DataGridHeader的DataTemplate里直接绑定IsSelectAll了,但是Debug后发现没有DataContext。

后来又使用<sdk:DataGridTemplateColumn Header="{Binding XXX}" /> 这种方法,倒是有DataContext,但是是个Binding类型,不起作用。

最后找到了上面的方法。虽然经常用ElementName属性,但是从没这么用过。感觉很奇妙。


下面是后台代码:

 

 
  
1 public partial class SelectAllPage : UserControl
2 {
3 private SelectAllViewModel _dataContext;
4
5 public SelectAllPage()
6 {
7 InitializeComponent();
8
9 this .Loaded += (s, e) =>
10 {
11 this .DataContext = _dataContext = new SelectAllViewModel();
12 };
13 }
14
15 private void AddColumn( object sender, RoutedEventArgs e)
16 {
17 _dataContext.AddUser();
18 }
19
20 private void DeleteColumn( object sender, RoutedEventArgs e)
21 {
22 _dataContext.DeleteUser();
23 }
24
25 }
26
27   public class SelectAllViewModel : INotifyPropertyChanged
28 {
29 public event PropertyChangedEventHandler PropertyChanged;
30 public ObservableCollection < UserViewModel > Users { get ; set ; }
31
32 public bool IsSelectAll
33 {
34 get
35 {
36 int userCount = Users.Count;
37 int selectedUserCount = Users.Count(u => u.IsSelected);
38 if (userCount == 0 ) // 如果一列没有,则处于不被选中状态
39   return false ;
40 return userCount == selectedUserCount; // 当被选中的人数与总人数相等时处于选中状态
41   }
42 set
43 {
44 foreach (var mapping in Users)
45 {
46 mapping.IsSelected = value;
47 }
48 }
49 }
50
51 public SelectAllViewModel()
52 {
53 // 在生成对象的时候注册PropertyChanged事件,这样当某个User被选中时就可以通知SelectAll进行状态更新
54   Users = new ObservableCollection < UserViewModel > ();
55 Users.Add( new UserViewModel(UserPropertyChanged));
56 Users.Add( new UserViewModel(UserPropertyChanged));
57 Users.Add( new UserViewModel(UserPropertyChanged));
58 Users.Add( new UserViewModel(UserPropertyChanged));
59
60 // 注册CollectionChanged事件
61   Users.CollectionChanged += UsersCollectionChanged;
62 }
63
64 public void AddUser()
65 {
66 Users.Add( new UserViewModel(UserPropertyChanged));
67 }
68
69 public void DeleteUser()
70 {
71 if (Users.Count > 0 )
72 Users.RemoveAt( 0 );
73 }
74
75 private void UserPropertyChanged( object sender, PropertyChangedEventArgs e)
76 {
77 if (e.PropertyName == " IsSelected " )
78 { // 如果是由于某一行前面的CheckBox被选中而触发改事件,则通知SelectAll更新时间
79   if ( this .PropertyChanged != null )
80 PropertyChanged( this , new PropertyChangedEventArgs( " IsSelectAll " ));
81 }
82 }
83 private void UsersCollectionChanged( object sender, NotifyCollectionChangedEventArgs e)
84 {
85 // 如果表格里增加了列或减少了列,也应该通知SelectAll更新状态
86 // 比如先全部选中,然后点击Add Column,这时新增加的列应该不被选中,因此SelectAll也应该不被选中
87   if ( this .PropertyChanged != null )
88 PropertyChanged( this , new PropertyChangedEventArgs( " IsSelectAll " ));
89 }
90 }
91
92 public class UserViewModel : INotifyPropertyChanged
93 {
94 private static int i = 0 ;
95 public event PropertyChangedEventHandler PropertyChanged;
96
97 public UserViewModel(PropertyChangedEventHandler eventHandler)
98 {
99 this .PropertyChanged += eventHandler;
100 }
101
102 public string Name
103 {
104 get { return " Name " + i ++ ; }
105 }
106
107 private bool _isSelected;
108 public bool IsSelected
109 {
110 get { return _isSelected; }
111 set
112 {
113 _isSelected = value;
114 if ( this .PropertyChanged != null ) // 不是为了通知界面更新CheckBox状态,而是为了通知SelectAll更新状态
115 PropertyChanged( this , new PropertyChangedEventArgs( " IsSelected " ));
116 }
117 }
118 }

 

 

这样就可以了。感觉Select All一般属于一种附属类的功能,如果大量使用EventHandler的话会感觉有点乱。

转载于:https://www.cnblogs.com/li-xiao/archive/2010/12/31/1923120.html

删除之类操作需要全选功能,方便选择 public class MainActivity extends Activity { private ListView lv; private MyAdapter mAdapter; private ArrayList list; private Button bt_selectall; // private Button bt_cancel; // private Button bt_deselectall; private int checkNum; // 记录选中的条目数量 private TextView tv_show;// 用于显示选中的条目数量 /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* 实例化各个控件 */ lv = (ListView) findViewById(R.id.lv); bt_selectall = (Button) findViewById(R.id.bt_selectall); // bt_cancel = (Button) findViewById(R.id.bt_cancelselectall); // bt_deselectall = (Button) findViewById(R.id.bt_deselectall); tv_show = (TextView) findViewById(R.id.tv); list = new ArrayList(); // 为Adapter准备数据 initDate(); // 实例化自定义的MyAdapter mAdapter = new MyAdapter(list, this); // 绑定Adapter lv.setAdapter(mAdapter); // 全选按钮的回调接口 bt_selectall.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 遍历list的长度,将MyAdapter中的map值全部设为true for (int i = 0; i < list.size(); i++) { MyAdapter.getIsSelected().put(i, true); } // 数量设为list的长度 checkNum = list.size(); // 刷新listview和TextView的显示 dataChanged(); } }); // 反选按钮的回调接口 // bt_cancel.setOnClickListener(new OnClickListener() { // @Override // public void onClick(View v) { // // 遍历list的长度,将已选的设为未选,未选的设为已选 // for (int i = 0; i < list.siz
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值