Adding empty class for eject optical drive action.
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 foreach (PropertyInfo pi in aObject.GetType().GetProperties())
109 AttributeObjectProperty[] attributes =
110 ((AttributeObjectProperty[]) pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
111 if (attributes.Length != 1)
116 AttributeObjectProperty attribute = attributes[0];
118 if (!IsPropertyTypeSupported(pi))
123 GetPropertyValueFromControl(iTableLayoutPanel.Controls[ctrlIndex+1], pi, aObject); //+1 otherwise we get the label
125 ctrlIndex+=2; //Jump over the label too
130 /// Extend this function to support reading new types of properties.
132 /// <param name="aObject"></param>
133 private void GetPropertyValueFromControl(Control aControl, PropertyInfo aInfo, T aObject)
135 if (aInfo.PropertyType == typeof(int))
137 NumericUpDown ctrl=(NumericUpDown)aControl;
138 aInfo.SetValue(aObject,(int)ctrl.Value);
140 else if (aInfo.PropertyType.IsEnum)
142 // Instantiate our enum
143 object enumValue= Activator.CreateInstance(aInfo.PropertyType);
144 // Parse our enum from combo box
145 enumValue = Enum.Parse(aInfo.PropertyType,((ComboBox)aControl).SelectedItem.ToString());
146 //enumValue = ((ComboBox)aControl).SelectedValue;
148 aInfo.SetValue(aObject, enumValue);
150 else if (aInfo.PropertyType == typeof(bool))
152 CheckBox ctrl = (CheckBox)aControl;
153 aInfo.SetValue(aObject, ctrl.Checked);
155 else if (aInfo.PropertyType == typeof(string))
157 TextBox ctrl = (TextBox)aControl;
158 aInfo.SetValue(aObject, ctrl.Text);
160 else if (aInfo.PropertyType == typeof(PropertyFile))
162 Button ctrl = (Button)aControl;
163 PropertyFile value = new PropertyFile {FullPath=ctrl.Text};
164 aInfo.SetValue(aObject, value);
166 //TODO: add support for other types here
171 /// Create a control for the given property.
173 /// <param name="aInfo"></param>
174 /// <param name="aAttribute"></param>
175 /// <param name="aObject"></param>
176 /// <returns></returns>
177 private Control CreateControlForProperty(PropertyInfo aInfo, AttributeObjectProperty aAttribute, T aObject)
179 if (aInfo.PropertyType == typeof(int))
181 //Integer properties are using numeric editor
182 NumericUpDown ctrl = new NumericUpDown();
183 ctrl.AutoSize = true;
184 ctrl.Minimum = Int32.Parse(aAttribute.Minimum);
185 ctrl.Maximum = Int32.Parse(aAttribute.Maximum);
186 ctrl.Increment = Int32.Parse(aAttribute.Increment);
187 ctrl.Value = (int)aInfo.GetValue(aObject);
190 else if (aInfo.PropertyType.IsEnum)
192 //Enum properties are using combo box
193 ComboBox ctrl = new ComboBox();
194 ctrl.AutoSize = true;
196 ctrl.DropDownStyle = ComboBoxStyle.DropDownList;
197 //Data source is fine but it gives us duplicate entries for duplicated enum values
198 //ctrl.DataSource = Enum.GetValues(aInfo.PropertyType);
200 //Therefore we need to explicitly create our items
201 Size cbSize = new Size(0,0);
202 foreach (string name in aInfo.PropertyType.GetEnumNames())
204 ctrl.Items.Add(name.ToString());
205 Graphics g = this.CreateGraphics();
206 //Since combobox autosize would not work we need to get measure text ourselves
207 SizeF size=g.MeasureString(name.ToString(), ctrl.Font);
208 cbSize.Width = Math.Max(cbSize.Width,(int)size.Width);
209 cbSize.Height = Math.Max(cbSize.Height, (int)size.Height);
212 //Make sure our combobox is large enough
213 ctrl.MinimumSize = cbSize;
215 // Instantiate our enum
216 object enumValue = Activator.CreateInstance(aInfo.PropertyType);
217 enumValue = aInfo.GetValue(aObject);
218 //Set the current item
219 ctrl.SelectedItem = enumValue.ToString();
223 else if (aInfo.PropertyType == typeof(bool))
225 CheckBox ctrl = new CheckBox();
226 ctrl.AutoSize = true;
227 ctrl.Text = aAttribute.Description;
228 ctrl.Checked = (bool)aInfo.GetValue(aObject);
231 else if (aInfo.PropertyType == typeof(string))
233 TextBox ctrl = new TextBox();
234 ctrl.AutoSize = true;
235 ctrl.Text = (string)aInfo.GetValue(aObject);
238 else if (aInfo.PropertyType == typeof(PropertyFile))
240 // We have a file property
241 // Create a button that will trigger the open file dialog to select our file.
242 Button ctrl = new Button();
243 ctrl.AutoSize = true;
244 ctrl.Text = ((PropertyFile)aInfo.GetValue(aObject)).FullPath;
246 // Add lambda expression to Click event
247 ctrl.Click += (sender, e) =>
249 // Create open file dialog
250 OpenFileDialog ofd = new OpenFileDialog();
251 ofd.RestoreDirectory = true;
252 // Use file filter specified by our property
253 ofd.Filter = aAttribute.Filter;
255 if (DlgBox.ShowDialog(ofd) == DialogResult.OK)
257 // Fetch selected file name
258 ctrl.Text = ofd.FileName;
259 //Enable Ok button then
260 buttonOk.Enabled = Object.IsValid();
266 //TODO: add support for other control type here
272 /// Don't forget to extend that one and adding types
274 /// <returns></returns>
275 private bool IsPropertyTypeSupported(PropertyInfo aInfo)
277 if (aInfo.PropertyType == typeof(int))
281 else if (aInfo.PropertyType.IsEnum)
285 else if (aInfo.PropertyType == typeof(bool))
289 else if (aInfo.PropertyType == typeof(string))
293 else if (aInfo.PropertyType == typeof(PropertyFile))
297 //TODO: add support for other type here
303 /// Update our table layout.
304 /// Will instantiated every field control as defined by our action.
305 /// Fields must be specified by rows from the left.
307 /// <param name="aLayout"></param>
308 private void UpdateTableLayoutPanel(T aObject)
311 //Debug.Print("UpdateTableLayoutPanel")
312 //First clean our current panel
313 iTableLayoutPanel.Controls.Clear();
314 iTableLayoutPanel.RowStyles.Clear();
315 iTableLayoutPanel.ColumnStyles.Clear();
316 iTableLayoutPanel.RowCount = 0;
318 //We always want two columns: one for label and one for the field
319 iTableLayoutPanel.ColumnCount = 2;
320 iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
321 iTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
330 //IEnumerable<PropertyInfo> properties = aObject.GetType().GetProperties().Where(
331 // prop => Attribute.IsDefined(prop, typeof(AttributeObjectProperty)));
334 foreach (PropertyInfo pi in aObject.GetType().GetProperties())
336 AttributeObjectProperty[] attributes = ((AttributeObjectProperty[])pi.GetCustomAttributes(typeof(AttributeObjectProperty), true));
337 if (attributes.Length != 1)
342 AttributeObjectProperty attribute = attributes[0];
344 //Before anything we need to check if that kind of property is supported by our UI
346 Control ctrl = CreateControlForProperty(pi, attribute, aObject);
349 //Property type not supported
354 iTableLayoutPanel.RowCount++;
355 iTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
357 Label label = new Label();
358 label.AutoSize = true;
359 label.Dock = DockStyle.Fill;
360 label.TextAlign = ContentAlignment.MiddleCenter;
361 label.Text = attribute.Name;
362 toolTip.SetToolTip(label, attribute.Description);
363 iTableLayoutPanel.Controls.Add(label, 0, iTableLayoutPanel.RowCount-1);
365 //Add our editor to our form
366 iTableLayoutPanel.Controls.Add(ctrl, 1, iTableLayoutPanel.RowCount - 1);
367 //Add tooltip to editor too
368 toolTip.SetToolTip(ctrl, attribute.Description);
374 private void buttonTest_Click(object sender, EventArgs e)
376 FetchPropertiesValue(Object);
378 //If our object has a test method with no parameters just run it then
379 MethodInfo info = Object.GetType().GetMethod("Test");
380 if ( info != null && info.GetParameters().Length==0)
382 info.Invoke(Object,null);