Adding non functional generic EAR HID 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;
16 using CodeProject.Dialog;
19 namespace SharpDisplayManager
22 /// Object edit dialog form.
24 public partial class FormEditObject<T> : Form where T: SharpLib.Ear.Object
26 public T Object = null;
28 public FormEditObject()
30 InitializeComponent();
36 /// <param name="sender"></param>
37 /// <param name="e"></param>
38 private void FormEditAction_Load(object sender, EventArgs e)
40 // Populate registered object types
41 IEnumerable < Type > types = Reflection.GetConcreteClassesDerivedFrom<T>();
42 foreach (Type type in types)
44 ItemObjectType item = new ItemObjectType(type);
45 comboBoxActionType.Items.Add(item);
50 // Creating new issue, select our first item
51 comboBoxActionType.SelectedIndex = 0;
55 // Editing existing object
56 // Look up our item in our combobox
57 foreach (ItemObjectType item in comboBoxActionType.Items)
59 if (item.Type == Object.GetType())
61 comboBoxActionType.SelectedItem = item;
67 private void buttonOk_Click(object sender, EventArgs e)
69 FetchPropertiesValue(Object);
70 if (!Object.IsValid())
72 // Tell for closing event to abort
73 DialogResult = DialogResult.None;
78 private void FormEditObject_FormClosing(object sender, FormClosingEventArgs e)
80 e.Cancel = DialogResult == DialogResult.None;
83 private void comboBoxActionType_SelectedIndexChanged(object sender, EventArgs e)
85 //Instantiate an action corresponding to our type
86 Type actionType = ((ItemObjectType) comboBoxActionType.SelectedItem).Type;
87 //Create another type of action only if needed
88 if (Object == null || Object.GetType() != actionType)
90 Object = (T)Activator.CreateInstance(actionType);
93 //Disable ok button if our object is not valid
94 buttonOk.Enabled = Object.IsValid();
97 UpdateTableLayoutPanel(Object);
102 /// Get properties values from our generated input fields
104 private void FetchPropertiesValue(T aObject)
107 //For each of our properties
108 foreach (PropertyInfo pi in aObject.GetType().GetProperties())
110 //Get our property attribute
111 AttributeObjectProperty[] attributes = ((AttributeObjectProperty[]) pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
112 if (attributes.Length != 1)
114 //No attribute, skip this property then.
117 AttributeObjectProperty attribute = attributes[0];
119 //Check that we support this type of property
120 if (!IsPropertyTypeSupported(pi))
125 //Now fetch our property value
126 GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aObject); //+1 otherwise we get the label
128 ctrlIndex+=2; //Jump over the label too
133 /// Extend this function to support reading new types of properties.
135 /// <param name="aObject"></param>
136 private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, T aObject)
138 if (aInfo.PropertyType == typeof(int))
140 NumericUpDown ctrl=(NumericUpDown)aControl;
141 aInfo.SetValue(aObject,(int)ctrl.Value);
143 else if (aInfo.PropertyType.IsEnum)
145 // Instantiate our enum
146 object enumValue= Activator.CreateInstance(aInfo.PropertyType);
147 // Parse our enum from combo box
148 enumValue = Enum.Parse(aInfo.PropertyType,((ComboBox)aControl).SelectedItem.ToString());
149 //enumValue = ((ComboBox)aControl).SelectedValue;
151 aInfo.SetValue(aObject, enumValue);
153 else if (aInfo.PropertyType == typeof(bool))
155 CheckBox ctrl = (CheckBox)aControl;
156 aInfo.SetValue(aObject, ctrl.Checked);
158 else if (aInfo.PropertyType == typeof(string))
160 TextBox ctrl = (TextBox)aControl;
161 aInfo.SetValue(aObject, ctrl.Text);
163 else if (aInfo.PropertyType == typeof(PropertyFile))
165 Button ctrl = (Button)aControl;
166 PropertyFile value = new PropertyFile {FullPath=ctrl.Text};
167 aInfo.SetValue(aObject, value);
169 else if (aInfo.PropertyType == typeof(PropertyComboBox))
171 ComboBox ctrl = (ComboBox)aControl;
172 string currentItem = ctrl.SelectedItem.ToString();
173 PropertyComboBox value = (PropertyComboBox)aInfo.GetValue(aObject);
174 value.CurrentItem = currentItem;
175 //Not strictly needed but makes sure the set method is called
176 aInfo.SetValue(aObject, value);
179 //TODO: add support for other types here
184 /// Create a control for the given property.
186 /// <param name="aInfo"></param>
187 /// <param name="aAttribute"></param>
188 /// <param name="aObject"></param>
189 /// <returns></returns>
190 private Control CreateControlForProperty(PropertyInfo aInfo, AttributeObjectProperty aAttribute, T aObject)
192 if (aInfo.PropertyType == typeof(int))
194 //Integer properties are using numeric editor
195 NumericUpDown ctrl = new NumericUpDown();
196 ctrl.AutoSize = true;
197 ctrl.Minimum = Int32.Parse(aAttribute.Minimum);
198 ctrl.Maximum = Int32.Parse(aAttribute.Maximum);
199 ctrl.Increment = Int32.Parse(aAttribute.Increment);
200 ctrl.Value = (int)aInfo.GetValue(aObject);
203 else if (aInfo.PropertyType.IsEnum)
205 //Enum properties are using combo box
206 ComboBox ctrl = new ComboBox();
207 ctrl.AutoSize = true;
209 ctrl.DropDownStyle = ComboBoxStyle.DropDownList;
210 //Data source is fine but it gives us duplicate entries for duplicated enum values
211 //ctrl.DataSource = Enum.GetValues(aInfo.PropertyType);
213 //Therefore we need to explicitly create our items
214 Size cbSize = new Size(0, 0);
215 foreach (string name in aInfo.PropertyType.GetEnumNames())
217 ctrl.Items.Add(name.ToString());
218 Graphics g = this.CreateGraphics();
219 //Since combobox autosize would not work we need to get measure text ourselves
220 SizeF size = g.MeasureString(name.ToString(), ctrl.Font);
221 cbSize.Width = Math.Max(cbSize.Width, (int)size.Width);
222 cbSize.Height = Math.Max(cbSize.Height, (int)size.Height);
225 //Make sure our combobox is large enough
226 ctrl.MinimumSize = cbSize;
228 // Instantiate our enum
229 object enumValue = Activator.CreateInstance(aInfo.PropertyType);
230 enumValue = aInfo.GetValue(aObject);
231 //Set the current item
232 ctrl.SelectedItem = enumValue.ToString();
236 else if (aInfo.PropertyType == typeof(bool))
238 CheckBox ctrl = new CheckBox();
239 ctrl.AutoSize = true;
240 ctrl.Text = aAttribute.Description;
241 ctrl.Checked = (bool)aInfo.GetValue(aObject);
244 else if (aInfo.PropertyType == typeof(string))
246 TextBox ctrl = new TextBox();
247 ctrl.AutoSize = true;
248 ctrl.Text = (string)aInfo.GetValue(aObject);
251 else if (aInfo.PropertyType == typeof(PropertyFile))
253 // We have a file property
254 // Create a button that will trigger the open file dialog to select our file.
255 Button ctrl = new Button();
256 ctrl.AutoSize = true;
257 ctrl.Text = ((PropertyFile)aInfo.GetValue(aObject)).FullPath;
259 // Add lambda expression to Click event
260 ctrl.Click += (sender, e) =>
262 // Create open file dialog
263 OpenFileDialog ofd = new OpenFileDialog();
264 ofd.RestoreDirectory = true;
265 // Use file filter specified by our property
266 ofd.Filter = aAttribute.Filter;
268 if (DlgBox.ShowDialog(ofd) == DialogResult.OK)
270 // Fetch selected file name
271 ctrl.Text = ofd.FileName;
272 //Enable Ok button then
273 buttonOk.Enabled = Object.IsValid();
279 else if (aInfo.PropertyType == typeof(PropertyComboBox))
282 ComboBox ctrl = new ComboBox();
283 ctrl.AutoSize = true;
285 ctrl.DropDownStyle = ComboBoxStyle.DropDownList;
286 //Data source is such a pain to set the current item
287 //ctrl.DataSource = ((PropertyComboBox)aInfo.GetValue(aObject)).Items;
289 PropertyComboBox pcb = ((PropertyComboBox)aInfo.GetValue(aObject));
290 foreach (string item in pcb.Items)
292 ctrl.Items.Add(item);
295 ctrl.SelectedItem = ((PropertyComboBox)aInfo.GetValue(aObject)).CurrentItem;
299 //TODO: add support for other control type here
304 /// Don't forget to extend that one and adding types
306 /// <returns></returns>
307 private bool IsPropertyTypeSupported(PropertyInfo aInfo)
309 if (aInfo.PropertyType == typeof(int))
313 else if (aInfo.PropertyType.IsEnum)
317 else if (aInfo.PropertyType == typeof(bool))
321 else if (aInfo.PropertyType == typeof(string))
325 else if (aInfo.PropertyType == typeof(PropertyFile))
329 else if (aInfo.PropertyType == typeof(PropertyComboBox))
334 //TODO: add support for other type here
340 /// Update our table layout.
341 /// Will instantiated every field control as defined by our action.
342 /// Fields must be specified by rows from the left.
344 /// <param name="aLayout"></param>
345 private void UpdateTableLayoutPanel(T aObject)
348 //Debug.Print("UpdateTableLayoutPanel")
349 //First clean our current panel
350 iTableLayoutPanel.Controls.Clear();
351 iTableLayoutPanel.RowStyles.Clear();
352 iTableLayoutPanel.ColumnStyles.Clear();
353 iTableLayoutPanel.RowCount = 0;
355 //We always want two columns: one for label and one for the field
356 iTableLayoutPanel.ColumnCount = 2;
357 iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
358 iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
367 //IEnumerable<PropertyInfo> properties = aObject.GetType().GetProperties().Where(
368 // prop => Attribute.IsDefined(prop, typeof(AttributeObjectProperty)));
371 foreach (PropertyInfo pi in aObject.GetType().GetProperties())
373 AttributeObjectProperty[] attributes = ((AttributeObjectProperty[])pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
374 if (attributes.Length != 1)
379 AttributeObjectProperty attribute = attributes[0];
381 //Before anything we need to check if that kind of property is supported by our UI
383 Control ctrl = CreateControlForProperty(pi, attribute, aObject);
386 //Property type not supported
391 iTableLayoutPanel.RowCount++;
392 iTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
394 Label label = new Label();
395 label.AutoSize = true;
396 label.Dock = DockStyle.Fill;
397 label.TextAlign = ContentAlignment.MiddleCenter;
398 label.Text = attribute.Name;
399 toolTip.SetToolTip(label, attribute.Description);
400 iTableLayoutPanel.Controls.Add(label, 0, iTableLayoutPanel.RowCount-1);
402 //Add our editor to our form
403 iTableLayoutPanel.Controls.Add(ctrl, 1, iTableLayoutPanel.RowCount - 1);
404 //Add tooltip to editor too
405 toolTip.SetToolTip(ctrl, attribute.Description);
411 private void buttonTest_Click(object sender, EventArgs e)
413 FetchPropertiesValue(Object);
415 //If our object has a test method with no parameters just run it then
416 MethodInfo info = Object.GetType().GetMethod("Test");
417 if ( info != null && info.GetParameters().Length==0)
419 info.Invoke(Object,null);