|
|
|
 |
 |
Исходник |
 |
|
 |
 |
|
Автор:
|
|
|
Название:
|
Design-time редактор для свойств типа enum с флагом Flags |
|
Дата:
|
02 November 2003 |
|
Описание: |
Необходим т.к. стандартный редактор для Enum некорректно работает, когда установлен атрибут Flags – не позволяет указать несколько значений. |
| |
Разместить ссылку на этот исходник в форуме вы можете вставив в текст сообщения
следующую строку:
[CODEPOST ID=63]Design-time редактор для свойств типа enum с флагом Flags[/CODEPOST] |
| Оценка: |
Проголосовало 2 посетителей, средняя оценка 3.00 |
| Оценить: |
|
1 using System;
2 using System.Drawing;
3 using System.Collections;
4 using System.Windows.Forms;
5 using System.Drawing.Design;
6 using System.Windows.Forms.Design;
7
8 namespace WandERRLib.Windows.Forms.Utils
9 {
10 /// <summary>
11 /// Класс редактора типов для перечислений с атрибутом Flags.
12 /// </summary>
13 public class FlagsEnumEditor : UITypeEditor
14 {
15 #region Переменные
16 internal IWindowsFormsEditorService edSvc = null;
17 #endregion
18
19 #region Методы
20 /// <summary>
21 /// Осуществляет редактирование.
22 /// </summary>
23 /// <param name="_context">объект с интерфейсом System.ComponentModel.ITypeDescriptorContext
24 /// для получения дополнительной информации</param>
25 /// <param name="_provider">объект с интерфейсом IServiceProvider
26 /// для получения дополнительных сервисов</param>
27 /// <param name="_value">текущее значение для редактирования</param>
28 /// <returns>новое (отредактированное) значение</returns>
29 public override object EditValue(System.ComponentModel.ITypeDescriptorContext _context, IServiceProvider _provider, object _value)
30 {
31 if((_context == null) || (_context.Instance == null) || (_provider == null))
32 return _value;
33
34 if((this.edSvc = (IWindowsFormsEditorService) _provider.GetService(typeof(IWindowsFormsEditorService))) == null)
35 return _value;
36
37 FlagsEnumEditorForm form = new FlagsEnumEditorForm(this);
38 form.EditValue = _value;
39 this.edSvc.DropDownControl(form);
40 _value = form.EditValue;
41 form.Dispose();
42
43 this.edSvc = null;
44
45 return _value;
46 }
47
48 /// <summary>
49 /// Определяет вид редактора.
50 /// </summary>
51 /// <param name="_context">объект с интерфейсом System.ComponentModel.ITypeDescriptorContext
52 /// для получения дополнительной информации</param>
53 /// <returns>тип редактора - UITypeEditorEditStyle.DropDown</returns>
54 public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext _context)
55 {
56 if((_context != null) && (_context.Instance != null))
57 return UITypeEditorEditStyle.DropDown;
58
59 return base.GetEditStyle(_context);
60 }
61 #endregion
62 }
63
64 internal class FlagsEnumListBox : CheckedListBox
65 {
66 #region Переменные
67 private int lockUpdate = 0;
68 #endregion
69
70 #region Конструкторы и деструкторы
71 public FlagsEnumListBox()
72 {
73 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
74 }
75 #endregion
76
77 #region Методы
78 public void ListBoxBeginUpdate()
79 {
80 this.BeginUpdate();
81 this.lockUpdate++;
82 }
83
84 public void ListBoxEndUpdate()
85 {
86 this.EndUpdate();
87 if(--this.lockUpdate == 0)
88 this.Invalidate();
89 }
90
91 protected override void OnPaint(PaintEventArgs _e)
92 {
93 if(this.lockUpdate != 0)
94 return;
95
96 base.OnPaint(_e);
97 }
98 #endregion
99 }
100
101 internal class FlagsEnumEditorForm : Form
102 {
103 #region Переменные
104 const string noneOption = "None";
105
106 private FlagsEnumEditor mainEditor;
107 private FlagsEnumListBox listBox;
108 private object editValue, originalValue;
109 private int lockCheckUpdate;
110 #endregion
111
112 #region Конструкторы и деструкторы
113 public FlagsEnumEditorForm(FlagsEnumEditor _editor)
114 {
115 this.lockCheckUpdate = 0;
116 this.mainEditor = _editor;
117 this.listBox = new FlagsEnumListBox();
118 this.listBox.Font = Control.DefaultFont;
119 this.listBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
120 this.listBox.Dock = DockStyle.Fill;
121 this.listBox.ItemCheck += new ItemCheckEventHandler(this.listBox_ItemCheckEventHandler);
122
123 #region Установка свойств формы редактора
124 this.StartPosition = FormStartPosition.WindowsDefaultBounds;
125 this.MaximizeBox = false;
126 this.MinimizeBox = false;
127 this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
128 this.TopLevel = false;
129 this.ShowInTaskbar = false;
130 this.TopMost = true;
131 this.Font = Control.DefaultFont;
132 this.ClientSize = new Size(0, this.listBox.ItemHeight * 7);
133 #endregion
134
135 this.Controls.Add(this.listBox);
136 }
137 #endregion
138
139 #region Методы
140 protected override bool ProcessDialogKey(Keys _keyData)
141 {
142 if(_keyData == Keys.Enter)
143 {
144 this.mainEditor.edSvc.CloseDropDown();
145 return true;
146 }
147 if(_keyData == Keys.Escape)
148 {
149 this.editValue = this.originalValue;
150 this.mainEditor.edSvc.CloseDropDown();
151 return true;
152 }
153 return base.ProcessDialogKey(_keyData);
154 }
155
156 protected void listBox_ItemCheckEventHandler(object _sender, ItemCheckEventArgs _e)
157 {
158 if(this.lockCheckUpdate != 0)
159 return;
160
161 this.BeginUpdate();
162
163 try
164 {
165 string optionName = this.listBox.Items[_e.Index].ToString();
166
167 if(_e.NewValue == CheckState.Checked)
168 this.EnableOption(optionName);
169 else
170 this.DisableOption(optionName);
171
172 this.UpdateListBox();
173 }
174 finally
175 {
176 this.EndUpdate();
177 }
178 }
179
180 void BeginUpdate()
181 {
182 this.lockCheckUpdate++;
183 }
184
185 void EndUpdate()
186 {
187 this.lockCheckUpdate--;
188 }
189
190 void SelectAll()
191 {
192 foreach(string optionName in this.listBox.Items)
193 {
194 if(optionName != noneOption)
195 this.EnableOption(optionName);
196 }
197 }
198
199 void ClearAll()
200 {
201 foreach(string optionName in this.listBox.Items)
202 {
203 if(optionName != noneOption)
204 this.DisableOption(optionName);
205 }
206 }
207
208 void UpdateListBox()
209 {
210 this.listBox.ListBoxBeginUpdate();
211 try
212 {
213 for(int n = 0; n < this.listBox.Items.Count; n++)
214 {
215 string optionName = this.listBox.Items[n].ToString();
216 this.listBox.SetItemChecked(n, this.IsOptionEnabled(optionName));
217 }
218 }
219 finally
220 {
221 this.listBox.ListBoxEndUpdate();
222 }
223 }
224
225 protected int GetOptionValue(string _optionName)
226 {
227 Type t = EditValue.GetType();
228 return (int) t.GetField(_optionName).GetValue(EditValue);
229 }
230
231 protected void ConvertFromInt(int _value)
232 {
233 Type t = EditValue.GetType();
234 this.editValue = Activator.CreateInstance(t);
235 t.GetFields()[0].SetValue(this.editValue, _value);
236 }
237
238 protected void DisableOption(string _optionName)
239 {
240 if(_optionName == noneOption)
241 {
242 this.SelectAll();
243 return;
244 }
245
246 ConvertFromInt((int) this.editValue & (~this.GetOptionValue(_optionName)));
247 }
248
249 protected void EnableOption(string _optionName)
250 {
251 if(_optionName == noneOption)
252 {
253 this.ClearAll();
254 return;
255 }
256
257 ConvertFromInt((int) this.editValue | this.GetOptionValue(_optionName));
258 }
259
260 protected bool IsOptionEnabled(string _optionName)
261 {
262 int opt = (int) this.editValue;
263
264 if(_optionName == noneOption)
265 return (opt == this.GetOptionValue(_optionName));
266
267 return (opt & this.GetOptionValue(_optionName)) == this.GetOptionValue(_optionName);
268 }
269
270 protected ArrayList GetFields(Type _t)
271 {
272 ArrayList list = new ArrayList();
273 System.Reflection.FieldInfo[] fields = _t.GetFields();
274
275 foreach(System.Reflection.FieldInfo field in fields)
276 {
277 if(field.IsSpecialName)
278 continue;
279
280 list.Add(field);
281 }
282 list.Sort(new FieldsComparer());
283
284 return list;
285 }
286 #endregion
287
288 #region Свойства
289 /// <summary>
290 /// Редактируемое свойство.
291 /// </summary>
292 public object EditValue
293 {
294 get { return editValue; }
295 set
296 {
297 if(this.editValue == value)
298 return;
299
300 this.originalValue = this.editValue = value;
301
302 this.listBox.Items.Clear();
303
304 ArrayList list = GetFields(editValue.GetType());
305 this.BeginUpdate();
306 try
307 {
308 foreach(System.Reflection.FieldInfo fi in list)
309 {
310 this.listBox.Items.Add(fi.Name, this.IsOptionEnabled(fi.Name) ? CheckState.Checked : CheckState.Unchecked);
311 }
312 }
313 finally
314 {
315 this.EndUpdate();
316 }
317
318 int maxItems = Math.Min(this.listBox.Items.Count, 15);
319 this.ClientSize = new Size(this.Size.Width, this.listBox.ItemHeight * maxItems);
320 }
321 }
322 #endregion
323
324 class FieldsComparer : IComparer
325 {
326 int IComparer.Compare(object x, object y)
327 {
328 System.Reflection.FieldInfo fi1 = x as System.Reflection.FieldInfo;
329 System.Reflection.FieldInfo fi2 = y as System.Reflection.FieldInfo;
330 if(fi1 == null || fi2 == null) return Comparer.Default.Compare(x, y);
331 if(fi1 == fi2) return 0;
332 if(fi1.Name == noneOption) return -1;
333 if(fi2.Name == noneOption) return 1;
334 return Comparer.Default.Compare(fi1.Name, fi2.Name);
335 }
336 }
337 }
338 }
339 |
| Вернуться к списку исходников в категории Winforms |
|
|
 |
 |
 |
 |
|
|