External/Aga.Controls/Tree/NodeControls/NodeComboBox.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 using System.Drawing;
     5 using System.Windows.Forms;
     6 using System.Reflection;
     7 using System.ComponentModel;
     8 using System.Drawing.Design;
     9 
    10 namespace Aga.Controls.Tree.NodeControls
    11 {
    12 	public class NodeComboBox : BaseTextControl
    13 	{
    14 		#region Properties
    15 
    16 		private int _editorWidth = 100;
    17 		[DefaultValue(100)]
    18 		public int EditorWidth
    19 		{
    20 			get { return _editorWidth; }
    21 			set { _editorWidth = value; }
    22 		}
    23 
    24 		private int _editorHeight = 100;
    25 		[DefaultValue(100)]
    26 		public int EditorHeight
    27 		{
    28 			get { return _editorHeight; }
    29 			set { _editorHeight = value; }
    30 		}
    31 
    32 		private List<object> _dropDownItems;
    33 		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists")]
    34 		[Editor(typeof(StringCollectionEditor), typeof(UITypeEditor)), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    35 		public List<object> DropDownItems
    36 		{
    37 			get { return _dropDownItems; }
    38 		}
    39 
    40 		#endregion
    41 
    42 		public event EventHandler<EditEventArgs> CreatingEditor;
    43 
    44 		public NodeComboBox()
    45 		{
    46 			_dropDownItems = new List<object>();
    47 		}
    48 
    49 		protected override Size CalculateEditorSize(EditorContext context)
    50 		{
    51 			if (Parent.UseColumns)
    52 			{
    53 				if (context.Editor is CheckedListBox)
    54 					return new Size(context.Bounds.Size.Width, EditorHeight);
    55 				else
    56 					return context.Bounds.Size;
    57 			}
    58 			else
    59 			{
    60 				if (context.Editor is CheckedListBox)
    61 					return new Size(EditorWidth, EditorHeight);
    62 				else
    63 					return new Size(EditorWidth, context.Bounds.Height);
    64 			}
    65 		}
    66 
    67 		protected override Control CreateEditor(TreeNodeAdv node)
    68 		{
    69 			Control c;
    70 			object value = GetValue(node);
    71 			if (IsCheckedListBoxRequired(node))
    72 				c = CreateCheckedListBox(node);
    73 			else
    74 				c = CreateCombo(node);
    75 			OnCreatingEditor(new EditEventArgs(node, c));
    76 			return c;
    77 		}
    78 
    79 		protected override void DisposeEditor(Control editor)
    80 		{
    81 		}
    82 
    83 		protected virtual void OnCreatingEditor(EditEventArgs args)
    84 		{
    85 			if (CreatingEditor != null)
    86 				CreatingEditor(this, args);
    87 		}
    88 
    89 		protected virtual bool IsCheckedListBoxRequired(TreeNodeAdv node)
    90 		{
    91 			object value = GetValue(node);
    92 			if (value != null)
    93 			{
    94 				Type t = value.GetType();
    95 				object[] arr = t.GetCustomAttributes(typeof(FlagsAttribute), false);
    96 				return (t.IsEnum && arr.Length == 1);
    97 			}
    98 			return false;
    99 		}
   100 
   101 		private Control CreateCombo(TreeNodeAdv node)
   102 		{
   103 			ComboBox comboBox = new ComboBox();
   104 			if (DropDownItems != null)
   105 				comboBox.Items.AddRange(DropDownItems.ToArray());
   106 			comboBox.SelectedItem = GetValue(node);
   107 			comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
   108 			comboBox.DropDownClosed += new EventHandler(EditorDropDownClosed);
   109 			SetEditControlProperties(comboBox, node);
   110 			return comboBox;
   111 		}
   112 
   113 		private Control CreateCheckedListBox(TreeNodeAdv node)
   114 		{
   115 			CheckedListBox listBox = new CheckedListBox();
   116 			listBox.CheckOnClick = true;
   117 
   118 			object value = GetValue(node);
   119 			Type enumType = GetEnumType(node);
   120 			foreach (object obj in Enum.GetValues(enumType))
   121 			{
   122 				object[] attributes = enumType.GetField(obj.ToString()).GetCustomAttributes(typeof(BrowsableAttribute), false);
   123 				if (attributes.Length == 0 || ((BrowsableAttribute)attributes[0]).Browsable)
   124 					listBox.Items.Add(obj, IsContain(value, obj));
   125 			}
   126 
   127 			SetEditControlProperties(listBox, node);
   128 			if (CreatingEditor != null)
   129 				CreatingEditor(this, new EditEventArgs(node, listBox));
   130 			return listBox;
   131 		}
   132 
   133 		protected virtual Type GetEnumType(TreeNodeAdv node)
   134 		{
   135 			object value = GetValue(node);
   136 			return value.GetType();
   137 		}
   138 
   139 		private bool IsContain(object value, object enumElement)
   140 		{
   141 			if (value == null || enumElement == null)
   142 				return false;
   143 			if (value.GetType().IsEnum)
   144 			{
   145 				int i1 = (int)value;
   146 				int i2 = (int)enumElement;
   147 				return (i1 & i2) == i2;
   148 			}
   149 			else
   150 			{
   151 				var arr = value as object[];
   152 				foreach (object obj in arr)
   153 					if ((int)obj == (int)enumElement)
   154 						return true;
   155 				return false;
   156 			}
   157 		}
   158 
   159 		protected override string FormatLabel(object obj)
   160 		{
   161 			var arr = obj as object[];
   162 			if (arr != null)
   163 			{
   164 				StringBuilder sb = new StringBuilder();
   165 				foreach (object t in arr)
   166 				{
   167 					if (sb.Length > 0)
   168 						sb.Append(", ");
   169 					sb.Append(t);
   170 				}
   171 				return sb.ToString();
   172 			}
   173 			else
   174 				return base.FormatLabel(obj);
   175 		}
   176 
   177 		void EditorDropDownClosed(object sender, EventArgs e)
   178 		{
   179 			EndEdit(true);
   180 		}
   181 
   182 		public override void UpdateEditor(Control control)
   183 		{
   184 			if (control is ComboBox)
   185 				(control as ComboBox).DroppedDown = true;
   186 		}
   187 
   188 		protected override void DoApplyChanges(TreeNodeAdv node, Control editor)
   189 		{
   190 			var combo = editor as ComboBox;
   191 			if (combo != null)
   192 			{
   193 				if (combo.DropDownStyle == ComboBoxStyle.DropDown)
   194 					SetValue(node, combo.Text);
   195 				else
   196 					SetValue(node, combo.SelectedItem);
   197 			}
   198 			else
   199 			{
   200 				var listBox = editor as CheckedListBox;
   201 				Type type = GetEnumType(node);
   202 				if (IsFlags(type))
   203 				{
   204 					int res = 0;
   205 					foreach (object obj in listBox.CheckedItems)
   206 						res |= (int)obj;
   207 					object val = Enum.ToObject(type, res);
   208 					SetValue(node, val);
   209 				}
   210 				else
   211 				{
   212 					List<object> list = new List<object>();
   213 					foreach (object obj in listBox.CheckedItems)
   214 						list.Add(obj);
   215 					SetValue(node, list.ToArray());
   216 				}
   217 			}
   218 		}
   219 
   220 		private bool IsFlags(Type type)
   221 		{
   222 			object[] atr = type.GetCustomAttributes(typeof(FlagsAttribute), false);
   223 			return atr.Length == 1;
   224 		}
   225 
   226 		public override void MouseUp(TreeNodeAdvMouseEventArgs args)
   227 		{
   228 			if (args.Node != null && args.Node.IsSelected) //Workaround of specific ComboBox control behavior
   229 				base.MouseUp(args);
   230 		}
   231 	}
   232 }