Rambler's Top100
Главная
Новости
Статьи
Форумы
Книги
Коды
Сообщество
Блоги
О нас
 

Логин

Email:
  Пароль:

Войти
Зарегистрироваться
Забыл пароль

Поиск

 Искать :
 
Вперед

Книги по теме

Искать:
в:
Порядок:

Исходник

Автор:

W@ndERR ®

 
Название:

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
 
Apartments for Rent

Rambler's Top100
Рейтинг@Mail.ru
Идея: Dimon aka Manowar Программирование: Dimon aka Manowar Дизайн: Dan Lebedev
Хостинг от компании Parking.ru
Карта сайта