Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / Design / Dialogs / ActivityBindForm.cs / 1305376 / ActivityBindForm.cs
using System; using System.Collections.Generic; using System.Globalization; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Workflow.ComponentModel; using System.ComponentModel.Design; using System.Workflow.ComponentModel.Compiler; using System.Reflection; using System.Diagnostics; using System.Collections.ObjectModel; using System.Windows.Forms.Design; using System.Diagnostics.CodeAnalysis; namespace System.Workflow.ComponentModel.Design { internal sealed partial class ActivityBindForm : Form { //ui control private ActivityBindFormWorkflowOutline workflowOutline = null; private IServiceProvider serviceProvider = null; private ITypeDescriptorContext context = null; private Type boundType = null; //returns private ActivityBind binding = null; private bool createNew = false;//create new field or use existing private bool createNewProperty = false;//create property or field private string newMemberName = string.Empty; private const string MemberTypeFormat = "MemberType#{0}";//non-localiazable, used for image list keys private string ActivityBindDialogTitleFormat;// = "Bind '{0}' to Activity Property"; private string PropertyAssignableFormat;// = "Selected property of type '{0}' is assignable to the target property type '{1}'."; private string DescriptionFormat;// = " It has description '{0}'."; private string EditIndex;// = " You may change index(es) on the selected tree item either by clicking on a node with the left mouse button or by pressing Alt-I."; private string PleaseSelectCorrectActivityProperty;// = "Select a property of type '{0}'. Currently selected property of type \"{1}\" isn't assignable to the target type."; private string PleaseSelectActivityProperty;// = "Select a property of type \"{0}\" on an activity from the workflow activity tree."; private string IncorrectIndexChange;// = "New index expression \"{0}\" is incorrect."; private string CreateNewMemberHelpFormat;// = "Enter new member name you want to be created on the root activity for property promotion, then choose the kind of member between either a field or a property.\nNew member will be of type '{0}'."; System.Windows.Forms.ImageList memberTypes = null; Listproperties; public ActivityBindForm(IServiceProvider serviceProvider, ITypeDescriptorContext context) { this.context = context; this.serviceProvider = serviceProvider; InitializeComponent(); this.createProperty.Checked = true;//make the property to be the default emitted entity this.helpTextBox.Multiline = true; //Set dialog fonts IUIService uisvc = (IUIService)this.serviceProvider.GetService(typeof(IUIService)); if (uisvc != null) this.Font = (Font)uisvc.Styles["DialogFont"]; //add images to the tree-view's imagelist System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ActivityBindForm)); ActivityBindDialogTitleFormat = resources.GetString("ActivityBindDialogTitleFormat"); PropertyAssignableFormat = resources.GetString("PropertyAssignableFormat"); DescriptionFormat = resources.GetString("DescriptionFormat"); EditIndex = resources.GetString("EditIndex"); PleaseSelectCorrectActivityProperty = resources.GetString("PleaseSelectCorrectActivityProperty"); PleaseSelectActivityProperty = resources.GetString("PleaseSelectActivityProperty"); IncorrectIndexChange = resources.GetString("IncorrectIndexChange"); CreateNewMemberHelpFormat = resources.GetString("CreateNewMemberHelpFormat"); this.memberTypes = new System.Windows.Forms.ImageList(); this.memberTypes.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("memberTypes.ImageStream"))); this.memberTypes.TransparentColor = AmbientTheme.TransparentColor; //this.memberTypes.Images.SetKeyName(0, "Field_Public"); //this.memberTypes.Images.SetKeyName(1, "Field_Internal"); //this.memberTypes.Images.SetKeyName(2, "Field_Protected"); //this.memberTypes.Images.SetKeyName(3, "Field_Private"); //this.memberTypes.Images.SetKeyName(4, "Property_Public"); //this.memberTypes.Images.SetKeyName(5, "Property_Internal"); //this.memberTypes.Images.SetKeyName(6, "Property_Protected"); //this.memberTypes.Images.SetKeyName(7, "Property_Private"); //this.memberTypes.Images.SetKeyName(8, "Constant_Public"); //this.memberTypes.Images.SetKeyName(9, "Constant_Internal"); //this.memberTypes.Images.SetKeyName(10, "Constant_Protected"); //this.memberTypes.Images.SetKeyName(11, "Constant_Private"); //this.memberTypes.Images.SetKeyName(12, "Event_Public"); //this.memberTypes.Images.SetKeyName(13, "Event_Internal"); //this.memberTypes.Images.SetKeyName(14, "Event_Protected"); //this.memberTypes.Images.SetKeyName(15, "Event_Private"); //this.memberTypes.Images.SetKeyName(16, "Delegate_Public"); //this.memberTypes.Images.SetKeyName(17, "Delegate_Internal"); //this.memberTypes.Images.SetKeyName(18, "Delegate_Protected"); //this.memberTypes.Images.SetKeyName(19, "Delegate_Private"); //this.memberTypes.Images.SetKeyName(20, "Index_Public"); //this.memberTypes.Images.SetKeyName(21, "Index_Internal"); //this.memberTypes.Images.SetKeyName(22, "Index_Protected"); //this.memberTypes.Images.SetKeyName(23, "Index_Private"); //preload custom properties before getting type from the type provider (as it would refresh the types) this.properties = CustomActivityDesignerHelper.GetCustomProperties(context); } #region return properties public ActivityBind Binding { get { return this.binding; } } public bool CreateNew { get { return this.createNew; } } public bool CreateNewProperty { get { return this.createNewProperty; } } public string NewMemberName { get { return this.newMemberName; } } #endregion private void ActivityBindForm_Load(object sender, EventArgs e) { this.Text = string.Format(CultureInfo.CurrentCulture, ActivityBindDialogTitleFormat, context.PropertyDescriptor.Name); if (this.context.PropertyDescriptor is DynamicPropertyDescriptor) this.boundType = PropertyDescriptorUtils.GetBaseType(this.context.PropertyDescriptor, PropertyDescriptorUtils.GetComponent(context), serviceProvider); if (this.boundType != null) { //lets get the same type through the type provider (otherwise this type may mismatch with the one obtained from the design time types) ITypeProvider typeProvider = this.serviceProvider.GetService(typeof(ITypeProvider)) as ITypeProvider; if (typeProvider != null) { Type designTimeType = typeProvider.GetType(this.boundType.FullName, false); this.boundType = (designTimeType != null) ? designTimeType : this.boundType; } } //create outline control this.workflowOutline = new ActivityBindFormWorkflowOutline(this.serviceProvider, this); this.dummyPanel.BorderStyle = BorderStyle.None; this.dummyPanel.SuspendLayout(); this.dummyPanel.Controls.Add(this.workflowOutline); this.workflowOutline.Location = new Point(3, 3); this.workflowOutline.Size = new Size(199, 351); this.workflowOutline.Dock = DockStyle.Fill; this.dummyPanel.ResumeLayout(false); this.workflowOutline.AddMemberKindImages(this.memberTypes); //make the outline view load initial state this.workflowOutline.ReloadWorkflowOutline(); //expand just the root node this.workflowOutline.ExpandRootNode(); //now we need to select the activity/path which was previously set //NOTE: we would have to expand all nodes on the way to make doc outline control populate their children Activity activity = PropertyDescriptorUtils.GetComponent(context) as Activity; if (activity == null) { IReferenceService rs = this.context.GetService(typeof(IReferenceService)) as IReferenceService; if (rs != null) activity = rs.GetComponent(this.context.Instance) as Activity; } ActivityBind previousBinding = context.PropertyDescriptor.GetValue(context.Instance) as ActivityBind; if (activity != null && previousBinding != null) { Activity previousBindActivity = Helpers.ParseActivity(Helpers.GetRootActivity(activity), previousBinding.Name); if (previousBindActivity != null) this.workflowOutline.SelectActivity(previousBindActivity, ParseStringPath(GetActivityType(previousBindActivity), previousBinding.Path)); } if (this.properties != null) { List customPropertyNames = new List (); foreach (CustomProperty customProperty in this.properties) customPropertyNames.Add(customProperty.Name); // set default name this.memberNameTextBox.Text = DesignerHelpers.GenerateUniqueIdentifier(this.serviceProvider, activity.Name + "_" + context.PropertyDescriptor.Name, customPropertyNames.ToArray()); } this.newMemberHelpTextBox.Lines = string.Format(CultureInfo.CurrentCulture, CreateNewMemberHelpFormat, GetSimpleTypeFullName(this.boundType)).Split(new char[] { '\n' }); } private void OKButton_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.None; this.createNew = (this.bindTabControl.SelectedIndex != this.bindTabControl.TabPages.IndexOf(this.existingMemberPage)); if (this.createNew) { // this.createNewProperty = this.createProperty.Checked; this.newMemberName = this.memberNameTextBox.Text; //validate name based on the prop promotion dialog this.DialogResult = ValidateNewMemberBind(this.newMemberName); } else { this.DialogResult = ValidateExistingPropertyBind(); } } private DialogResult ValidateExistingPropertyBind() { Activity activity = this.workflowOutline.SelectedActivity; PathInfo member = this.workflowOutline.SelectedMember; string propertyPath = this.workflowOutline.PropertyPath;//the path on the PathInfo will be incorrect if user had changed indexes if (activity == null || member == null) { string message = SR.GetString(SR.Error_BindDialogNoValidPropertySelected, GetSimpleTypeFullName(this.boundType)); DesignerHelpers.ShowError(this.serviceProvider, message); return DialogResult.None; } Type parsedPropertyType = member.PropertyType; //lets get the same type through the type provider (otherwise this type may mismatch with the one obtained from the design time types) ITypeProvider typeProvider = this.serviceProvider.GetService(typeof(ITypeProvider)) as ITypeProvider; if (typeProvider != null && parsedPropertyType != null) { Type designTimeParsedType = typeProvider.GetType(parsedPropertyType.FullName, false); parsedPropertyType = (designTimeParsedType != null) ? designTimeParsedType : parsedPropertyType; } if (this.boundType != parsedPropertyType && !TypeProvider.IsAssignable(this.boundType, parsedPropertyType)) { string message = SR.GetString(SR.Error_BindDialogWrongPropertyType, GetSimpleTypeFullName(parsedPropertyType), GetSimpleTypeFullName(this.boundType)); DesignerHelpers.ShowError(this.serviceProvider, message); return DialogResult.None; } //this is the selected activity which property is being bound Activity bindingActivity = PropertyDescriptorUtils.GetComponent(this.context) as Activity; //this is the name of the property we are binding string propertyName = context.PropertyDescriptor.Name; if (bindingActivity == activity && member != null && member.Path.Equals(propertyName, StringComparison.Ordinal)) { DesignerHelpers.ShowError(this.serviceProvider, SR.GetString(SR.Error_BindDialogCanNotBindToItself)); return DialogResult.None; } if (activity != null && member != null) { // ActivityBind bind = new ActivityBind(activity.QualifiedName, propertyPath); ValidationManager manager = new ValidationManager(this.serviceProvider); PropertyValidationContext propertyValidationContext = new PropertyValidationContext(this.context.Instance, DependencyProperty.FromName(this.context.PropertyDescriptor.Name, this.context.Instance.GetType())); manager.Context.Append(this.context.Instance);// ValidationErrorCollection errors; using (WorkflowCompilationContext.CreateScope(manager)) { errors = ValidationHelpers.ValidateProperty(manager, bindingActivity, bind, propertyValidationContext); } if (errors != null && errors.Count > 0 && errors.HasErrors) { string message = string.Empty; for (int i = 0; i < errors.Count; i++) { ValidationError error = errors[i]; message += error.ErrorText + ((i == errors.Count - 1) ? string.Empty : "; "); } message = SR.GetString(SR.Error_BindDialogBindNotValid) + message; DesignerHelpers.ShowError(this.serviceProvider, message); return DialogResult.None; } else { this.binding = bind; return DialogResult.OK; } } return DialogResult.None; } [SuppressMessage("Microsoft.Globalization", "CA130:UseOrdinalStringComparison", MessageId="System.String.Compare(System.String,System.String,System.Boolean,System.Globalization.CultureInfo)", Justification="This is a design time method and so there is no security issue")] private DialogResult ValidateNewMemberBind(string newMemberName) { Activity activity = PropertyDescriptorUtils.GetComponent(context) as Activity; if (activity == null) { IReferenceService rs = this.context.GetService(typeof(IReferenceService)) as IReferenceService; if (rs != null) activity = rs.GetComponent(this.context.Instance) as Activity; } string errorMsg = null; try { ValidationHelpers.ValidateIdentifier(context, newMemberName); } catch { errorMsg = SR.GetString(SR.Error_InvalidLanguageIdentifier, newMemberName); } // get all the members of the custom activity to ensure uniqueness Type customActivityType = CustomActivityDesignerHelper.GetCustomActivityType(context); SupportedLanguages language = CompilerHelpers.GetSupportedLanguage(context); foreach (MemberInfo memberInfo in customActivityType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) { if (string.Compare(memberInfo.Name, newMemberName, language == SupportedLanguages.VB, CultureInfo.InvariantCulture) == 0) { errorMsg = SR.GetString(SR.Failure_FieldAlreadyExist); break; } } // ctor name should be checked separately if (errorMsg == null && string.Compare(customActivityType.Name, newMemberName, language == SupportedLanguages.VB, CultureInfo.InvariantCulture) == 0) errorMsg = SR.GetString(SR.Failure_FieldAlreadyExist); if (errorMsg == null) { ActivityBind newBind = new ActivityBind(ActivityBind.GetRelativePathExpression(Helpers.GetRootActivity(activity), activity), newMemberName); IDesignerHost host = this.context.GetService(typeof(IDesignerHost)) as IDesignerHost; if (host == null) throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(IDesignerHost).FullName)); this.binding = newBind; } else { DesignerHelpers.ShowError(context, errorMsg); } return ((errorMsg == null) ? DialogResult.OK : DialogResult.None); } private void cancelButton_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.Cancel; } private void SelectedActivityChanged(Activity activity, PathInfo memberPathInfo, string path) { string helpMessage = string.Empty; string desiredType = GetSimpleTypeFullName(this.boundType); if (memberPathInfo != null) { if (path == null || path.Length == 0) { helpMessage = string.Format(CultureInfo.CurrentCulture, PleaseSelectActivityProperty, desiredType); } else { string memberName = MemberActivityBindTreeNode.MemberName(memberPathInfo.Path); string memberType = GetSimpleTypeFullName(memberPathInfo.PropertyType); string memberDescription = GetMemberDescription(memberPathInfo.MemberInfo); if (TypeProvider.IsAssignable(this.boundType, memberPathInfo.PropertyType)) helpMessage = string.Format(CultureInfo.CurrentCulture, PropertyAssignableFormat, memberType, desiredType) + ((memberDescription.Length > 0) ? string.Format(CultureInfo.CurrentCulture, DescriptionFormat, memberDescription) : string.Empty); else helpMessage = string.Format(CultureInfo.CurrentCulture, PleaseSelectCorrectActivityProperty, desiredType, memberType); helpMessage += ((MemberActivityBindTreeNode.MemberName(path).IndexOfAny(new char[] { '[', ']' }) != -1) ? EditIndex : string.Empty); } } else { helpMessage = string.Format(CultureInfo.CurrentCulture, PleaseSelectActivityProperty, desiredType); } this.helpTextBox.Lines = helpMessage.Split(new char[]{'\n'}); } private List PopulateAutoCompleteList(Activity activity, PathInfo path) { List currentPropertyList = new List (); Type activityType = GetActivityType(activity); PathInfo[] subProps = (activityType != null) ? ProcessPaths(activityType, path) : null; if (subProps != null) currentPropertyList.AddRange(subProps); return currentPropertyList; } private Type GetActivityType(Activity activity) { Type activityType = null; IDesignerHost designerHost = this.serviceProvider.GetService(typeof(IDesignerHost)) as IDesignerHost; WorkflowDesignerLoader loader = this.serviceProvider.GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader; if (designerHost != null && loader != null && activity.Parent == null) { ITypeProvider typeProvider = this.serviceProvider.GetService(typeof(ITypeProvider)) as ITypeProvider; if (typeProvider != null) activityType = typeProvider.GetType(designerHost.RootComponentClassName, false); } if (activityType == null) activityType = activity.GetType(); return activityType; } #region help - related private void ActivityBindForm_HelpButtonClicked(object sender, CancelEventArgs e) { e.Cancel = true; GetHelp(); } protected override void OnHelpRequested(HelpEventArgs e) { e.Handled = true; GetHelp(); } private void GetHelp() { DesignerHelpers.ShowHelpFromKeyword(this.serviceProvider, typeof(ActivityBindForm).FullName + ".UI"); } #endregion //given activity and current path, process all immediate children properties of the selected property private PathInfo[] ProcessPaths(Type activityType, PathInfo topProperty) { List paths = new List (); if (topProperty == null) { paths.AddRange(GetSubPropertiesOnType(activityType, string.Empty)); } else //topProperty != null { //sub properties on activity properties paths.AddRange(GetSubPropertiesOnType(topProperty.PropertyType, topProperty.Path)); } return paths.ToArray(); } private PathInfo[] GetArraySubProperties(Type propertyType, string currentPath)//(PathInfo pathInfo) { List paths = new List (); if (propertyType != typeof(string))//ignore char item[int] on the string { List getterMethodInfos = new List (); MemberInfo[] arrayMembers = null; try { arrayMembers = propertyType.GetDefaultMembers(); } catch (NotImplementedException) { //Even if we encounted a RTTTypeWrapper that doesnt implement GetDefaultMemebers dont crash. //we should atleast be able to continue to bind to other members of the type. } catch (ArgumentException) { // This is a work-around for DevDiv Bugs 109401. Type.GetDefaultMembers() can throw // ArgumentException in certain circumstances. In order to avoid crashing the designer host // (typically VS), we must handle the exception and ignore the offending type. } if (arrayMembers != null && arrayMembers.Length > 0) { foreach (MemberInfo member in arrayMembers) { if (member is PropertyInfo) getterMethodInfos.Add((member as PropertyInfo).GetGetMethod()); } } if (propertyType.IsArray) { MemberInfo[] getMembers = propertyType.GetMember("Get");//arrays will always implement that if (getMembers != null && getMembers.Length > 0) { foreach (MemberInfo member in getMembers) if (member is MethodInfo) getterMethodInfos.Add(member as MethodInfo); } } foreach (MethodInfo info in getterMethodInfos) { string indexString = ConstructIndexString(info); if (indexString != null) { //add array accessor paths.Add(new PathInfo(currentPath + indexString, info, info.ReturnType)); } } } return paths.ToArray(); } private string ConstructIndexString(MethodInfo getterMethod) { StringBuilder indexString = new StringBuilder(); ParameterInfo[] parameters = getterMethod.GetParameters(); if (parameters != null && parameters.Length > 0) { indexString.Append("["); for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameter = parameters[i]; string subIndex = GetIndexerString(parameter.ParameterType); if (subIndex == null) return null; indexString.Append(subIndex); if (i < parameters.Length - 1) indexString.Append(","); } indexString.Append("]"); } return indexString.ToString(); } private string GetIndexerString(Type indexType) { //The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Char, Double, and Single. object defaultIndexerInstance = null; if (IsTypePrimitive(indexType)) { try { //we'll just new the instance and get the string value out of the default one defaultIndexerInstance = Activator.CreateInstance(indexType); } catch { defaultIndexerInstance = null; } } else if (indexType == typeof(string)) { defaultIndexerInstance = "\" \""; } return (defaultIndexerInstance != null) ? defaultIndexerInstance.ToString() : null; } PropertyInfo[] GetProperties(Type type) { List members = new List (); members.AddRange(type.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.FlattenHierarchy)); if (type.IsInterface) { Type[] interfaces = type.GetInterfaces(); foreach (Type implementedInterface in interfaces) { members.AddRange(implementedInterface.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)); } } return members.ToArray(); } //quite expensive - uses reflection to go over all public properties/field/events private PathInfo[] GetSubPropertiesOnType(Type typeToGetPropertiesOn, string currentPath) { List paths = new List (); if (typeToGetPropertiesOn == typeof(string) || (TypeProvider.IsAssignable(typeof(System.Delegate), typeToGetPropertiesOn) && !this.boundType.IsSubclassOf(typeof(Delegate))))//ignore char item[int] on the string return paths.ToArray(); currentPath = (string.IsNullOrEmpty(currentPath)) ? string.Empty : currentPath + "."; ITypeProvider typeProvider = this.serviceProvider.GetService(typeof(ITypeProvider)) as ITypeProvider; foreach (PropertyInfo property in GetProperties(typeToGetPropertiesOn)) { MethodInfo getterMethod = property.GetGetMethod(); Type memberType = BindHelpers.GetMemberType(property); if (memberType == null) continue; if (typeProvider != null) { Type designTimeMemberType = typeProvider.GetType(memberType.FullName, false); memberType = (designTimeMemberType != null) ? designTimeMemberType : memberType; } //if (memberType == typeof(WorkflowParameterBindingCollection) && string.IsNullOrEmpty(currentPath)) //{ // //special case for the parameters collection on an activity itself (when path is empty) // Activity activity = this.workflowOutline.SelectedActivity; // if(getterMethod != null && typeToGetPropertiesOn == activity.GetType()) // { // WorkflowParameterBindingCollection collection = getterMethod.Invoke(activity, null) as WorkflowParameterBindingCollection; // if (collection != null) // { // foreach (WorkflowParameterBinding parameterBinding in collection) // { // //note that the currentPath is always empty // paths.Add(new PathInfo(property.Name + "[\"" + parameterBinding.ParameterName + "\"].Value", typeof(object))); // } // } // } //} //if it's a primitive and not equal to the desired type, skip it. //skip properties of type object if the target property is not object if (IsPropertyBrowsable(property) && getterMethod != null && memberType != null && (!IsTypePrimitive(memberType) || TypeProvider.IsAssignable(this.boundType, memberType)) && !((this.boundType != typeof(object) && memberType == typeof(object)))) { //some properties are indexers... analyze the parameters on the getter method // C#: at design time indexer property is called "this" while at runtime it gets renamed to "Item" // VB: indexer is called Item at design and runtime . string propertyName = property.Name; propertyName = currentPath + propertyName + ConstructIndexString(getterMethod); paths.Add(new PathInfo(propertyName, property, memberType)); paths.AddRange(GetArraySubProperties(memberType, propertyName)); } } // foreach (FieldInfo field in typeToGetPropertiesOn.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy))//BindingFlags.Static is needed for the const fields { Type fieldType = BindHelpers.GetMemberType(field); if (fieldType == null) continue; if (TypeProvider.IsAssignable(typeof(DependencyProperty), fieldType)) continue;//dont want to show all static public dependency properties fields if (typeProvider != null) { Type designTimeFieldType = typeProvider.GetType(fieldType.FullName, false); fieldType = (designTimeFieldType != null) ? designTimeFieldType : fieldType; } //if it's a primitive and not equal to the desired type, skip it. // if (IsPropertyBrowsable(field) && fieldType != null && (!IsTypePrimitive(fieldType) || TypeProvider.IsAssignable(this.boundType, fieldType)) && //primitive fields should only be shown for primitive properties !(this.boundType != typeof(object) && fieldType == typeof(object)) && //fields of type object should only be shown for properties of type object !(!TypeProvider.IsAssignable(typeof(Delegate), this.boundType) && TypeProvider.IsAssignable(typeof(Delegate), fieldType)))//fields of type delegate should only be shown for delegate properties { string fieldName = currentPath + field.Name; paths.Add(new PathInfo(fieldName, field, BindHelpers.GetMemberType(field))); paths.AddRange(GetArraySubProperties(fieldType, fieldName)); } } //we will populate events only if the target type is event (since it is always going to be the last valid entry in the path) if (this.boundType.IsSubclassOf(typeof(Delegate)))//System.MulticastDelegate ??? { foreach (EventInfo eventInfo in typeToGetPropertiesOn.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)) { Type eventType = BindHelpers.GetMemberType(eventInfo); if (eventType == null) continue; if (typeProvider != null) { Type designTimeEventType = typeProvider.GetType(eventType.FullName, false); eventType = (designTimeEventType != null) ? designTimeEventType : eventType; } if (IsPropertyBrowsable(eventInfo) && eventType != null && TypeProvider.IsAssignable(this.boundType, eventType)) paths.Add(new PathInfo(currentPath + eventInfo.Name, eventInfo, eventType)); } } return paths.ToArray(); } private string GetMemberDescription(MemberInfo member) { object[] descriptions = member.GetCustomAttributes(typeof(DescriptionAttribute), false); if (descriptions != null && descriptions.Length > 0) { DescriptionAttribute description = descriptions[0] as DescriptionAttribute; return (description != null) ? description.Description : string.Empty; } return string.Empty; } //given user typed path, find all properties along it and return them in the list private List ParseStringPath(Type activityType, string path) { if (string.IsNullOrEmpty(path)) return null; List pathInfoList = new List (); PathWalker pathWalker = new PathWalker(); PathMemberInfoEventArgs finalEventArgs = null; PathErrorInfoEventArgs errorEventArgs = null; pathWalker.MemberFound += delegate(object sender, PathMemberInfoEventArgs eventArgs) { finalEventArgs = eventArgs; //store the latest args pathInfoList.Add(new PathInfo(eventArgs.Path, eventArgs.MemberInfo, BindHelpers.GetMemberType(eventArgs.MemberInfo))); }; pathWalker.PathErrorFound += delegate(object sender, PathErrorInfoEventArgs eventArgs) { errorEventArgs = eventArgs; //store the error args }; pathWalker.TryWalkPropertyPath(activityType, path); return pathInfoList; } private bool IsPropertyBrowsable(MemberInfo property) { object[] attributes = property.GetCustomAttributes(typeof(BrowsableAttribute), false); if (attributes.Length > 0) { BrowsableAttribute attribute = attributes[0] as BrowsableAttribute; if (attribute != null) return attribute.Browsable; else { AttributeInfoAttribute attributeInfoAttribute = attributes[0] as AttributeInfoAttribute; if (attributeInfoAttribute != null) { ReadOnlyCollection
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DefaultAsyncDataDispatcher.cs
- ColorPalette.cs
- SelectedDatesCollection.cs
- sqlnorm.cs
- DetailsViewDesigner.cs
- InputLanguageSource.cs
- CompatibleIComparer.cs
- RelationalExpressions.cs
- OracleConnectionFactory.cs
- DataGridViewLinkColumn.cs
- NameValuePair.cs
- TraceSection.cs
- XmlCharCheckingWriter.cs
- VariableQuery.cs
- Timer.cs
- ServiceOperationWrapper.cs
- DiffuseMaterial.cs
- ChannelBinding.cs
- Point4D.cs
- DocumentViewer.cs
- Msec.cs
- HttpResponse.cs
- CodeGeneratorOptions.cs
- XmlSerializableWriter.cs
- _AutoWebProxyScriptEngine.cs
- BooleanSwitch.cs
- ReflectionUtil.cs
- CompilationSection.cs
- PageContentCollection.cs
- GenericsInstances.cs
- XmlValidatingReader.cs
- ViewGenResults.cs
- CodeAttributeArgument.cs
- DocumentViewer.cs
- DBPropSet.cs
- ButtonChrome.cs
- SafeNativeMethods.cs
- MailWriter.cs
- ListViewUpdateEventArgs.cs
- Assert.cs
- BookmarkNameHelper.cs
- Command.cs
- UiaCoreTypesApi.cs
- SystemNetHelpers.cs
- AbstractSvcMapFileLoader.cs
- VectorAnimationUsingKeyFrames.cs
- XmlObjectSerializerWriteContextComplex.cs
- ControlFilterExpression.cs
- SmtpFailedRecipientsException.cs
- PeerNameRecord.cs
- IdleTimeoutMonitor.cs
- DocumentCollection.cs
- CssClassPropertyAttribute.cs
- HandoffBehavior.cs
- GatewayIPAddressInformationCollection.cs
- Function.cs
- RequestCachePolicyConverter.cs
- HttpHandlerActionCollection.cs
- metrodevice.cs
- LoadWorkflowCommand.cs
- MetaType.cs
- SafeMemoryMappedFileHandle.cs
- CheckableControlBaseAdapter.cs
- DataGridViewRowCancelEventArgs.cs
- CodeArrayIndexerExpression.cs
- ControlUtil.cs
- Predicate.cs
- DataGridTextBoxColumn.cs
- TextRunTypographyProperties.cs
- ProxyGenerator.cs
- FormatStringEditor.cs
- StringExpressionSet.cs
- ApplicationFileParser.cs
- GridViewDeletedEventArgs.cs
- TrackingMemoryStreamFactory.cs
- WebBrowserEvent.cs
- EntityTypeEmitter.cs
- ColumnHeaderConverter.cs
- Annotation.cs
- LogicalMethodInfo.cs
- UIPermission.cs
- DataGridCellsPresenter.cs
- ProtocolState.cs
- Invariant.cs
- WeakEventManager.cs
- InitiatorSessionSymmetricMessageSecurityProtocol.cs
- SvcMapFile.cs
- FormatException.cs
- DebugView.cs
- SqlBooleanMismatchVisitor.cs
- CachingParameterInspector.cs
- CodeAssignStatement.cs
- InternalResources.cs
- Visual3D.cs
- RelationshipDetailsRow.cs
- LicFileLicenseProvider.cs
- xmlfixedPageInfo.cs
- DrawingBrush.cs
- LinearGradientBrush.cs
- SrgsGrammarCompiler.cs