Adding HID consumer control event.
2 using System.Collections.Generic;
3 using System.ComponentModel;
5 using System.Diagnostics;
9 using System.Threading.Tasks;
10 using System.Windows.Forms;
11 using SharpLib.Display;
13 using System.Reflection;
14 using Microsoft.VisualBasic.CompilerServices;
17 namespace SharpDisplayManager
20 /// Object edit dialog form.
22 public partial class FormEditObject<T> : Form where T : class
24 public T Object = null;
26 public FormEditObject()
28 InitializeComponent();
34 /// <param name="sender"></param>
35 /// <param name="e"></param>
36 private void FormEditAction_Load(object sender, EventArgs e)
38 // Populate registered object types
39 IEnumerable < Type > types = Reflection.GetConcreteClassesDerivedFrom<T>();
40 foreach (Type type in types)
42 ItemObjectType item = new ItemObjectType(type);
43 comboBoxActionType.Items.Add(item);
48 // Creating new issue, select our first item
49 comboBoxActionType.SelectedIndex = 0;
53 // Editing existing object
54 // Look up our item in our combobox
55 foreach (ItemObjectType item in comboBoxActionType.Items)
57 if (item.Type == Object.GetType())
59 comboBoxActionType.SelectedItem = item;
65 private void buttonOk_Click(object sender, EventArgs e)
67 FetchPropertiesValue(Object);
70 private void FormEditAction_Validating(object sender, CancelEventArgs e)
75 private void comboBoxActionType_SelectedIndexChanged(object sender, EventArgs e)
77 //Instantiate an action corresponding to our type
78 Type actionType = ((ItemObjectType) comboBoxActionType.SelectedItem).Type;
79 //Create another type of action only if needed
80 if (Object == null || Object.GetType() != actionType)
82 Object = (T)Activator.CreateInstance(actionType);
86 UpdateTableLayoutPanel(Object);
91 /// Get properties values from our generated input fields
93 private void FetchPropertiesValue(T aObject)
96 foreach (PropertyInfo pi in aObject.GetType().GetProperties())
98 AttributeObjectProperty[] attributes =
99 ((AttributeObjectProperty[]) pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
100 if (attributes.Length != 1)
105 AttributeObjectProperty attribute = attributes[0];
107 if (!IsPropertyTypeSupported(pi))
112 GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aObject); //+1 otherwise we get the label
114 ctrlIndex+=2; //Jump over the label too
119 /// Extend this function to support reading new types of properties.
121 /// <param name="aObject"></param>
122 private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, T aObject)
124 if (aInfo.PropertyType == typeof(int))
126 NumericUpDown ctrl=(NumericUpDown)aControl;
127 aInfo.SetValue(aObject,(int)ctrl.Value);
129 else if (aInfo.PropertyType.IsEnum)
131 // Instantiate our enum
132 object enumValue= Activator.CreateInstance(aInfo.PropertyType);
133 // Parse our enum from combo box
134 enumValue = Enum.Parse(aInfo.PropertyType,((ComboBox)aControl).SelectedItem.ToString());
135 //enumValue = ((ComboBox)aControl).SelectedValue;
137 aInfo.SetValue(aObject, enumValue);
139 else if (aInfo.PropertyType == typeof(bool))
141 CheckBox ctrl = (CheckBox)aControl;
142 aInfo.SetValue(aObject, ctrl.Checked);
144 else if (aInfo.PropertyType == typeof(string))
146 TextBox ctrl = (TextBox)aControl;
147 aInfo.SetValue(aObject, ctrl.Text);
149 //TODO: add support for other types here
154 /// Create a control for the given property.
156 /// <param name="aInfo"></param>
157 /// <param name="aAttribute"></param>
158 /// <param name="aObject"></param>
159 /// <returns></returns>
160 private Control CreateControlForProperty(PropertyInfo aInfo, AttributeObjectProperty aAttribute, T aObject)
162 if (aInfo.PropertyType == typeof(int))
164 //Integer properties are using numeric editor
165 NumericUpDown ctrl = new NumericUpDown();
166 ctrl.AutoSize = true;
167 ctrl.Minimum = Int32.Parse(aAttribute.Minimum);
168 ctrl.Maximum = Int32.Parse(aAttribute.Maximum);
169 ctrl.Increment = Int32.Parse(aAttribute.Increment);
170 ctrl.Value = (int)aInfo.GetValue(aObject);
173 else if (aInfo.PropertyType.IsEnum)
175 //Enum properties are using combo box
176 ComboBox ctrl = new ComboBox();
177 ctrl.AutoSize = true;
179 ctrl.DropDownStyle = ComboBoxStyle.DropDownList;
180 //Data source is fine but it gives us duplicate entries for duplicated enum values
181 //ctrl.DataSource = Enum.GetValues(aInfo.PropertyType);
183 //Therefore we need to explicitly create our items
184 Size cbSize = new Size(0,0);
185 foreach (string name in aInfo.PropertyType.GetEnumNames())
187 ctrl.Items.Add(name.ToString());
188 Graphics g = this.CreateGraphics();
189 //Since combobox autosize would not work we need to get measure text ourselves
190 SizeF size=g.MeasureString(name.ToString(), ctrl.Font);
191 cbSize.Width = Math.Max(cbSize.Width,(int)size.Width);
192 cbSize.Height = Math.Max(cbSize.Height, (int)size.Height);
195 //Make sure our combobox is large enough
196 ctrl.MinimumSize = cbSize;
198 // Instantiate our enum
199 object enumValue = Activator.CreateInstance(aInfo.PropertyType);
200 enumValue = aInfo.GetValue(aObject);
201 //Set the current item
202 ctrl.SelectedItem = enumValue.ToString();
206 else if (aInfo.PropertyType == typeof(bool))
208 CheckBox ctrl = new CheckBox();
209 ctrl.AutoSize = true;
210 ctrl.Text = aAttribute.Description;
211 ctrl.Checked = (bool)aInfo.GetValue(aObject);
214 else if (aInfo.PropertyType == typeof(string))
216 TextBox ctrl = new TextBox();
217 ctrl.AutoSize = true;
218 ctrl.Text = (string)aInfo.GetValue(aObject);
221 //TODO: add support for other control type here
227 /// Don't forget to extend that one and adding types
229 /// <returns></returns>
230 private bool IsPropertyTypeSupported(PropertyInfo aInfo)
232 if (aInfo.PropertyType == typeof(int))
236 else if (aInfo.PropertyType.IsEnum)
240 else if (aInfo.PropertyType == typeof(bool))
244 else if (aInfo.PropertyType == typeof(string))
248 //TODO: add support for other type here
254 /// Update our table layout.
255 /// Will instantiated every field control as defined by our action.
256 /// Fields must be specified by rows from the left.
258 /// <param name="aLayout"></param>
259 private void UpdateTableLayoutPanel(T aObject)
262 //Debug.Print("UpdateTableLayoutPanel")
263 //First clean our current panel
264 iTableLayoutPanel.Controls.Clear();
265 iTableLayoutPanel.RowStyles.Clear();
266 iTableLayoutPanel.ColumnStyles.Clear();
267 iTableLayoutPanel.RowCount = 0;
269 //We always want two columns: one for label and one for the field
270 iTableLayoutPanel.ColumnCount = 2;
271 iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
272 iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
281 //IEnumerable<PropertyInfo> properties = aObject.GetType().GetProperties().Where(
282 // prop => Attribute.IsDefined(prop, typeof(AttributeObjectProperty)));
285 foreach (PropertyInfo pi in aObject.GetType().GetProperties())
287 AttributeObjectProperty[] attributes = ((AttributeObjectProperty[])pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
288 if (attributes.Length != 1)
293 AttributeObjectProperty attribute = attributes[0];
295 //Before anything we need to check if that kind of property is supported by our UI
297 Control ctrl = CreateControlForProperty(pi, attribute, aObject);
300 //Property type not supported
305 iTableLayoutPanel.RowCount++;
306 iTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
308 Label label = new Label();
309 label.AutoSize = true;
310 label.Dock = DockStyle.Fill;
311 label.TextAlign = ContentAlignment.MiddleCenter;
312 label.Text = attribute.Name;
313 toolTip.SetToolTip(label, attribute.Description);
314 iTableLayoutPanel.Controls.Add(label, 0, iTableLayoutPanel.RowCount-1);
316 //Add our editor to our form
317 iTableLayoutPanel.Controls.Add(ctrl, 1, iTableLayoutPanel.RowCount - 1);
318 //Add tooltip to editor too
319 toolTip.SetToolTip(ctrl, attribute.Description);
325 private void buttonTest_Click(object sender, EventArgs e)
327 FetchPropertiesValue(Object);
329 //If our object has a test method with no parameters just run it then
330 MethodInfo info = Object.GetType().GetMethod("Test");
331 if ( info != null && info.GetParameters().Length==0)
333 info.Invoke(Object,null);