/// <summary> /// Obtain the parameters for <paramref name="method"/> and put them in <paramref name="defaultParameterValues"/> /// </summary> /// <param name="method">The method to Obtain parameters from</param> /// <param name="defaultParameterValues">The list that will be used as the storage for the retrieved parameters, if it contains elements, those elements will be used as default value</param> /// <returns>True if successed, false otherwise</returns> public static Object[] GetParams(MethodInfo method, Object[] defaultParameterValues) { List <ParameterInfo> parameterList = new List <ParameterInfo>(); List <Object> defaultParameterValueList = new List <object>(); #region find all the generic types and options and add that to the lists. if (method.ContainsGenericParameters) { ExposableMethodAttribute att = (method.GetCustomAttributes(typeof(ExposableMethodAttribute), false)[0] as ExposableMethodAttribute); Type[] typeOptions = att.GenericParametersOptions; int[] optionSize = att.GenericParametersOptionSizes; GenericParameter[] genericOptions = new GenericParameter[optionSize.Length]; int count = 0; for (int i = 0; i < optionSize.Length; i++) { Type[] types = new Type[optionSize[i]]; for (int j = 0; j < types.Length; j++) { types[j] = typeOptions[count++]; } genericOptions[i] = new GenericParameter(types[0], types); } //Type[] instanceGenericParameters = method.ReflectedType.GetGenericArguments(); Type[] genericTypes = method.GetGenericArguments(); for (int i = 0; i < genericTypes.Length; i++) { parameterList.Add(null); defaultParameterValueList.Add( defaultParameterValues == null ? genericOptions[i]: defaultParameterValues[i]); } } #endregion parameterList.AddRange(method.GetParameters()); if (defaultParameterValues != null) { defaultParameterValueList.AddRange(defaultParameterValues); } //if the method requires no parameter, simply return an empty array if (parameterList.Count == 0) { return(new object[0]); } #region Handle the cases where at least one parameter is required as input using (ParameterInputDialog dlg = new ParameterInputDialog(parameterList.ToArray(), defaultParameterValueList.ToArray())) { dlg.ShowDialog(); return(dlg.Successed ? dlg.Parameters : null); } #endregion }
/// <summary> /// Obtain the parameters for <paramref name="method"/> and put them in <paramref name="defaultParameterValues"/> /// </summary> /// <param name="method">The method to Obtain parameters from</param> /// <param name="defaultParameterValues">The list that will be used as the storage for the retrieved parameters, if it contains elements, those elements will be used as default value</param> /// <returns>True if successed, false otherwise</returns> public static Object[] GetParams(MethodInfo method, Object[] defaultParameterValues) { List<ParameterInfo> parameterList = new List<ParameterInfo>(); List<Object> defaultParameterValueList = new List<object>(); #region find all the generic types and options and add that to the lists. if (method.ContainsGenericParameters) { ExposableMethodAttribute att = (method.GetCustomAttributes(typeof(ExposableMethodAttribute), false)[0] as ExposableMethodAttribute); Type[] typeOptions = att.GenericParametersOptions; int[] optionSize = att.GenericParametersOptionSizes; GenericParameter[] genericOptions = new GenericParameter[optionSize.Length]; int count = 0; for (int i = 0; i < optionSize.Length; i++) { Type[] types = new Type[optionSize[i]]; for (int j = 0; j < types.Length; j++) types[j] = typeOptions[count++]; genericOptions[i] = new GenericParameter(types[0], types); } //Type[] instanceGenericParameters = method.ReflectedType.GetGenericArguments(); Type[] genericTypes = method.GetGenericArguments(); for (int i = 0; i < genericTypes.Length; i++) { parameterList.Add(null); defaultParameterValueList.Add( defaultParameterValues == null ? genericOptions[i]: defaultParameterValues[i]); } } #endregion parameterList.AddRange(method.GetParameters()); if (defaultParameterValues != null) defaultParameterValueList.AddRange(defaultParameterValues); //if the method requires no parameter, simply return an empty array if (parameterList.Count == 0) return new object[0]; #region Handle the cases where at least one parameter is required as input ParameterInputDialog dlg = new ParameterInputDialog(parameterList.ToArray(), defaultParameterValueList.ToArray()); dlg.ShowDialog(); return dlg.Successed ? dlg.Parameters : null; #endregion }
private ToolStripMenuItem[] BuildOperationTree(IEnumerable <KeyValuePair <string, MethodInfo> > catalogMiPairList) { List <ToolStripMenuItem> res = new List <ToolStripMenuItem>(); SortedDictionary <String, List <KeyValuePair <String, MethodInfo> > > catalogDic = new SortedDictionary <string, List <KeyValuePair <String, MethodInfo> > >(); SortedDictionary <String, MethodInfo> operationItem = new SortedDictionary <string, MethodInfo>(); foreach (KeyValuePair <string, MethodInfo> pair in catalogMiPairList) { if (String.IsNullOrEmpty(pair.Key)) { //this is an operation operationItem.Add(pair.Value.ToString(), pair.Value); } else { //this is a category int index = pair.Key.IndexOf('|'); String category; String subcategory; if (index == -1) { //There is no sub category category = pair.Key; subcategory = string.Empty; } else { //There are sub categories category = pair.Key.Substring(0, index); subcategory = pair.Key.Substring(index + 1, pair.Key.Length - index - 1); } if (!catalogDic.ContainsKey(category)) { catalogDic.Add(category, new List <KeyValuePair <String, MethodInfo> >()); } catalogDic[category].Add(new KeyValuePair <String, MethodInfo>(subcategory, pair.Value)); } } #region Add catalogs to the menu foreach (String catalog in catalogDic.Keys) { ToolStripMenuItem catalogMenuItem = new ToolStripMenuItem(); catalogMenuItem.Text = catalog; catalogMenuItem.DropDownItems.AddRange(BuildOperationTree(catalogDic[catalog])); res.Add(catalogMenuItem); } #endregion #region Add Methods to the menu foreach (MethodInfo mi in operationItem.Values) { ToolStripMenuItem operationMenuItem = new ToolStripMenuItem(); operationMenuItem.Size = new Size(152, 22); Type[] genericArgs = mi.GetGenericArguments(); String genericArgString = genericArgs.Length > 0 ? String.Format( "<{0}>", String.Join(",", Array.ConvertAll <Type, String>( genericArgs, System.Convert.ToString))) : string.Empty; operationMenuItem.Text = String.Format( "{0}{1}({2})", mi.Name.Substring(0, 1).Equals("_") ? mi.Name.Substring(1, mi.Name.Length - 1) : mi.Name, //remove leading underscore genericArgString, String.Join(",", System.Array.ConvertAll <ParameterInfo, String>(mi.GetParameters(), delegate(ParameterInfo pi) { return(pi.Name); }))); //This is necessary to handle delegate with a loop //Cause me lots of headache before reading the article on //http://decav.com/blogs/andre/archive/2007/11/18/wtf-quot-problems-quot-with-anonymous-delegates-linq-lambdas-and-quot-foreach-quot-or-quot-for-quot-loops.aspx //I wishes MSFT handle this better MethodInfo methodInfoRef = mi; operationMenuItem.Click += delegate { Object[] paramList = null; while (true) { //Get the parameters for the method //this pop up an input dialog and ask for user input paramList = ParameterInputDialog.GetParams(methodInfoRef, paramList); if (paramList == null) { break; //user click cancel on the input dialog } //create an operation from the specific methodInfo and parameter list Operation operation = new Operation(methodInfoRef, paramList); try { PushOperation(operation); break; } catch (Exception expt) { MessageBox.Show((expt.InnerException ?? expt).Message); //special case, then there is no parameter and the method throw an exception //break the loop if (methodInfoRef.GetParameters().Length == 0) { break; } } } }; res.Add(operationMenuItem); } #endregion return(res.ToArray()); }
/// <summary> /// Obtain the parameters for <paramref name="method"/> and put them in <paramref name="paramList"/> /// </summary> /// <param name="method">The method to Obtain parameters from</param> /// <param name="defaultParameterValues">The list that will be used as the storage for the retrieved parameters, if it contains elements, those elements will be used as default value</param> /// <returns>True if successed, false otherwise</returns> public static Object[] GetParams(MethodInfo method, Object[] defaultParameterValues) { List<ParameterInfo> parameterList = new List<ParameterInfo>(); List<Object> defaultParameterValueList = new List<object>(); #region find all the generic types and options and add that to the lists. if (method.ContainsGenericParameters) { String[] genericOptions = (method.GetCustomAttributes(typeof(ExposableMethodAttribute), false)[0] as ExposableMethodAttribute) .GenericParametersOptions.Split(';'); Type[] instanceGenericParameters = method.ReflectedType.GetGenericArguments(); Type[] genericTypes = method.GetGenericArguments(); for (int i = 0; i < genericTypes.Length; i++) { parameterList.Add(null); defaultParameterValueList.Add( defaultParameterValues == null ? String.Format( "{0}|{1}", genericTypes[i].Name, genericOptions[i].Substring(0, 1).Equals(":") ? instanceGenericParameters[i].FullName + genericOptions[i] : genericOptions[i]) : defaultParameterValues[i]); } } #endregion parameterList.AddRange(method.GetParameters()); if (defaultParameterValues != null) { defaultParameterValueList.AddRange(defaultParameterValues); } //if the method requires no parameter, simply return an empty array if (parameterList.Count == 0) { return new object[0]; } #region Handle the cases where at least one parameter is required as input ParameterInputDialog dlg = new ParameterInputDialog(parameterList.ToArray(), defaultParameterValueList.ToArray()); dlg.ShowDialog(); return dlg.Successed ? dlg.Parameters : null; #endregion }