您的位置:首页 > 编程语言

综合应用WPF/WCF/WF/LINQ之三:采用用代码创建的方式实现CheckListBox的CustomControl

2008-01-09 12:07 936 查看
实现CheckListBox的方法很多。我们可以直接在XAML文件中的ListBox控件中,嵌入CheckBox控件。但更多的时候,我们还是希望能把它编写成一个CustomControl以方便直接使用。
  以我们的Eallies OA系统为例,实现CheckListBox的CustomControl的方法如下:
  1、在Eallies.OA.UI.Controls.Common项目中添加一个CustomControl的项目,并让其继承于System.Windows.Controls.ListBox类。

1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Windows;
7 using System.Windows.Controls;
8 using System.Windows.Data;
9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15
16 namespace Eallies.OA.UI.Controls.Common
17 {
18 public class CheckListBox : ListBox
19 {
20 static CheckListBox()
21 {
22 DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckListBox), new FrameworkPropertyMetadata(typeof(CheckListBox)));
23 }
24 }
25 }  2、Themes目录下会自动生成Generic.xaml文件。为了不致于这个文件太过复杂,我们将关于CheckListBox的内容独立出来。在Themes目录下加入一个Resource Dictionary的项目,并更改其内容。

1 <ResourceDictionary
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:Eallies.OA.UI.Controls.Common">
5
6 <Style TargetType="{x:Type local:CheckListBox}" BasedOn="{StaticResource {x:Type ListBox}}" />
7
8 </ResourceDictionary>  3、Themes目录下的Generic.xaml文件也需要做一些修改。

1 <ResourceDictionary
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:Eallies.OA.UI.Controls.Common">
5
6 <ResourceDictionary.MergedDictionaries>
7 <ResourceDictionary Source="/Eallies.OA.UI.Controls.Common;component/Themes/CheckListBox.xaml" />
8 </ResourceDictionary.MergedDictionaries>
9
10 </ResourceDictionary>  4、之后,我们就可以为这个CustomControl添加自定义的内容了。CheckListBox控件需要一个用于保存列表项的属性,幸运的是,DataContext属性可以完成这点;它还需要一个用于保存已选择的列表项的属性,因此我们添加一个CheckedItems属性;为了支持通过DataContext属性或者直接AddItem的方法添加列表项,我们增加了OnPropertyChanged、AddItem、AddCheckedItem等方法。

1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Windows;
7 using System.Windows.Controls;
8 using System.Windows.Data;
9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 using Eallies.OA.Utility;
16
17 namespace Eallies.OA.UI.Controls.Common
18 {
19 public class CheckListBox : ListBox
20 {
21 private Dictionary<int, CheckListItem> _Items = new Dictionary<int, CheckListItem>();
22 private Dictionary<int, CheckListItem> _CheckedItems = new Dictionary<int, CheckListItem>();
23
24 static CheckListBox()
25 {
26 DefaultStyleKeyProperty.OverrideMetadata(typeof(CheckListBox), new FrameworkPropertyMetadata(typeof(CheckListBox)));
27 }
28
29 #region Public Properties
30
31 public Dictionary<int, CheckListItem> CheckedItems
32 {
33 get { return this._CheckedItems; }
34 set { this._CheckedItems = value; }
35 }
36
37 #endregion
38
39 protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
40 {
41 try
42 {
43 if (e.Property.Name != "ItemsSource" && e.Property.Name != "DataContext")
44 {
45 base.OnPropertyChanged(e);
46 }
47
48 if (e.Property.Name == "DataContext")
49 {
50 this._Items = e.NewValue as Dictionary<int, CheckListItem>;
51 }
52 }
53 catch
54 {
55 throw;
56 }
57 }
58
59 public void AddItem(bool ischecked, string content, int value)
60 {
61 try
62 {
63 this._Items.Add(value, new CheckListItem(ischecked, content, value));
64
65 if (ischecked == true)
66 {
67 this._CheckedItems.Add(value, new CheckListItem(true, content, value));
68 }
69 }
70 catch
71 {
72 throw;
73 }
74 }
75
76 public void AddCheckedItem(string content, int value)
77 {
78 try
79 {
80 if (this._CheckedItems.ContainsKey(value) == false)
81 {
82 this._CheckedItems.Add(value, new CheckListItem(true, content, value));
83 }
84 }
85 catch
86 {
87 throw;
88 }
89 }
90
91 public void Refresh()
92 {
93 try
94 {
95 this.Items.Clear();
96
97 foreach (CheckListItem item in this._Items.Values)
98 {
99 CheckBox checkbox = new CheckBox();
100
101 if (this._CheckedItems.ContainsKey(item.Value) == true) checkbox.IsChecked = true;
102 if (this._CheckedItems.ContainsKey(item.Value) != true) checkbox.IsChecked = false;
103 checkbox.Content = item.Content;
104 checkbox.Tag = item.Value;
105 checkbox.Checked += new RoutedEventHandler(CheckBox_Checked);
106 checkbox.Unchecked += new RoutedEventHandler(CheckBox_Unchecked);
107
108 this.Items.Add(checkbox);
109 }
110 }
111 catch
112 {
113 throw;
114 }
115 }
116
117 private void CheckBox_Checked(object sender, RoutedEventArgs e)
118 {
119 try
120 {
121 CheckBox checkbox = sender as CheckBox;
122 int key = checkbox.Tag.ToType<int>();
123
124 this._CheckedItems.Add(key, this._Items[key]);
125 }
126 catch
127 {
128 throw;
129 }
130 }
131
132 private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
133 {
134 try
135 {
136 CheckBox checkbox = sender as CheckBox;
137 int key = checkbox.Tag.ToType<int>();
138
139 this._CheckedItems.Remove(key);
140 }
141 catch
142 {
143 throw;
144 }
145 }
146
147 #region CheckListItem
148
149 public class CheckListItem
150 {
151 private bool _IsChecked = false;
152 private string _Content = string.Empty;
153 private int _Value = -1;
154
155 public CheckListItem(bool ischecked, string content, int value)
156 {
157 this._IsChecked = ischecked;
158 this._Content = content;
159 this._Value = value;
160 }
161
162 public bool IsChecked
163 {
164 get { return this._IsChecked; }
165 set { this._IsChecked = value; }
166 }
167
168 public string Content
169 {
170 get { return this._Content; }
171 set { this._Content = value; }
172 }
173
174 public int Value
175 {
176 get { return this._Value; }
177 set { this._Value = value; }
178 }
179 }
180
181 #endregion
182 }
183 }  5、现在我们可以在自己的项目中使用这个CustomControl了。首先需要更改XAML文件,添加引用:xmlns:common="clr-namespace:Eallies.OA.UI.Controls.Common;assembly=Eallies.OA.UI.Controls.Common",然后我们就可以使用这个控件了。

1 <logical:PageBase
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:logical="clr-namespace:Eallies.OA.UI.Controls.Logical;assembly=Eallies.OA.UI.Controls.Logical"
5 xmlns:common="clr-namespace:Eallies.OA.UI.Controls.Common;assembly=Eallies.OA.UI.Controls.Common"
6 x:Class="Eallies.OA.UI.User.Detail">
7 <Grid>
8 <Grid VerticalAlignment="Top">
9 <common:CheckListBox Margin="0,0,0,0" Name="lstRoles" Width="180" Height="180" HorizontalAlignment="Left" VerticalAlignment="Top" />
10 </Grid>
11 </Grid>
12 </logical:PageBase>  6、后台操纵这个控件的代码就很简单了。注意如果采用AddItem的方式添加列表项,则添加完毕后需要调用Refresh方法。

1 private void GetRoles()
2 {
3 RoleContractClient client = new RoleContractClient();
4
5 try
6 {
7 IList list = client.GetRoles();
8
9 if (list != null)
10 {
11 for (int i = 0; i < list.Count; i++)
12 {
13 RoleInfo functionInfo = list[i] as RoleInfo;
14
15 this.lstRoles.AddItem(false, functionInfo.RoleName, functionInfo.RoleId);
16 }
17 }
18
19 this.lstRoles.Refresh();
20 }
21 catch
22 {
23 throw;
24 }
25 finally
26 {
27 client.Close();
28 }
29 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐