|
namespace System.Workflow.ComponentModel.Design
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Workflow.ComponentModel.Serialization;
using System.ComponentModel.Design.Serialization;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Design;
using System.Security.Permissions;
using System.Xml;
using System.Workflow.ComponentModel.Compiler;
using System.Collections.ObjectModel;
#region Class WorkflowDesignerLoader
[PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public abstract class WorkflowDesignerLoader : BasicDesignerLoader
{
#region Members, Construction and Dispose
internal const string DesignerLayoutFileExtension = ".layout";
private CustomActivityDesignerAdapter customActivityDesignerAdapter;
private WorkflowDesignerEventsCoordinator eventsCoordinator;
private Hashtable createdServices = null;
private bool loadingDesignerLayout = false;
static WorkflowDesignerLoader()
{
ComponentDispenser.RegisterComponentExtenders(typeof(CustomActivityDesignerAdapter), new IExtenderProvider[] { new CustomActivityPropertyExtender() });
}
protected override void Initialize()
{
base.Initialize();
//PLEASE NOTE THE FOLLOWING CODE IS ADDED TO MAKE THE SPECIFIC DESIGNER TYPE INTERNAL
//This is a work around for invoke workflow so that the ActivityHostDesignerType does not become public
//Please refer to file WorkflowInlining.cs
Type invokeWorkflowType = Type.GetType(InvokeWorkflowDesigner.InvokeWorkflowRef);
if (invokeWorkflowType != null)
TypeDescriptor.AddAttributes(invokeWorkflowType, new DesignerAttribute(typeof(InvokeWorkflowDesigner), typeof(IDesigner)));
//Add all the services, it is important to make sure that if user pushes the services then we honor
//those services
LoaderHost.AddService(typeof(WorkflowDesignerLoader), this);
ServiceCreatorCallback callback = new ServiceCreatorCallback(OnCreateService);
if (LoaderHost.GetService(typeof(IWorkflowCompilerOptionsService)) == null)
LoaderHost.AddService(typeof(IWorkflowCompilerOptionsService), callback);
if (LoaderHost.GetService(typeof(IIdentifierCreationService)) == null)
LoaderHost.AddService(typeof(IIdentifierCreationService), callback);
if (LoaderHost.GetService(typeof(ComponentSerializationService)) == null)
LoaderHost.AddService(typeof(ComponentSerializationService), callback);
LoaderHost.RemoveService(typeof(IReferenceService));
if (LoaderHost.GetService(typeof(IReferenceService)) == null)
LoaderHost.AddService(typeof(IReferenceService), callback);
if (LoaderHost.GetService(typeof(IDesignerVerbProviderService)) == null)
LoaderHost.AddService(typeof(IDesignerVerbProviderService), callback);
//Add all the extenders, the extenders are responsible to add the extended properties which are not
//actual properties on activity
IExtenderProviderService extenderProviderService = GetService(typeof(IExtenderProviderService)) as IExtenderProviderService;
if (extenderProviderService != null)
{
foreach (IExtenderProvider extender in ComponentDispenser.Extenders)
extenderProviderService.AddExtenderProvider(extender);
}
this.customActivityDesignerAdapter = new CustomActivityDesignerAdapter(LoaderHost);
}
public override void Dispose()
{
if (this.eventsCoordinator != null)
{
((IDisposable)this.eventsCoordinator).Dispose();
this.eventsCoordinator = null;
}
if (this.customActivityDesignerAdapter != null)
{
((IDisposable)this.customActivityDesignerAdapter).Dispose();
this.customActivityDesignerAdapter = null;
}
IExtenderProviderService extenderProviderService = GetService(typeof(IExtenderProviderService)) as IExtenderProviderService;
if (extenderProviderService != null)
{
foreach (IExtenderProvider extender in ComponentDispenser.Extenders)
extenderProviderService.RemoveExtenderProvider(extender);
}
if (LoaderHost != null)
{
if (this.createdServices != null)
{
foreach (Type serviceType in this.createdServices.Keys)
{
LoaderHost.RemoveService(serviceType);
OnDisposeService(serviceType, this.createdServices[serviceType]);
}
this.createdServices.Clear();
this.createdServices = null;
}
LoaderHost.RemoveService(typeof(WorkflowDesignerLoader));
}
base.Dispose();
}
#endregion
#region Public Methods and Properties
public abstract TextReader GetFileReader(string filePath);
public abstract TextWriter GetFileWriter(string filePath);
public abstract string FileName { get; }
public virtual void ForceReload()
{
Reload(ReloadOptions.Force);
}
public override void Flush()
{
base.Flush();
}
public virtual bool InDebugMode
{
get
{
return false;
}
}
protected virtual TypeDescriptionProvider TargetFrameworkTypeDescriptionProvider
{
get
{
return null;
}
}
void AddTargetFrameworkProvider(IComponent component)
{
TypeDescriptionProviderService typeDescriptionProviderService = GetService(typeof(TypeDescriptionProviderService)) as TypeDescriptionProviderService;
if (typeDescriptionProviderService != null && component != null)
{
TypeDescriptor.AddProvider(typeDescriptionProviderService.GetProvider(component), component);
}
}
public void AddActivityToDesigner(Activity activity)
{
if (activity == null)
throw new ArgumentNullException("activity");
IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
if (designerHost == null)
throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(IDesignerHost).FullName));
if (activity.Parent == null && designerHost.RootComponent == null)
{
string fullClassName = activity.GetValue(WorkflowMarkupSerializer.XClassProperty) as String;
string rootSiteName = (!string.IsNullOrEmpty(fullClassName)) ? Helpers.GetClassName(fullClassName) : Helpers.GetClassName(activity.GetType().FullName);
designerHost.Container.Add(activity, rootSiteName);
AddTargetFrameworkProvider(activity);
}
else
{
designerHost.Container.Add(activity, activity.QualifiedName);
AddTargetFrameworkProvider(activity);
}
if (activity is CompositeActivity)
{
foreach (Activity activity2 in Helpers.GetNestedActivities(activity as CompositeActivity))
{
designerHost.Container.Add(activity2, activity2.QualifiedName);
AddTargetFrameworkProvider(activity2);
}
}
}
public void RemoveActivityFromDesigner(Activity activity)
{
if (activity == null)
throw new ArgumentNullException("activity");
IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
if (designerHost == null)
throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(IDesignerHost).FullName));
designerHost.DestroyComponent(activity);
if (activity is CompositeActivity)
{
foreach (Activity activity2 in Helpers.GetNestedActivities(activity as CompositeActivity))
designerHost.DestroyComponent(activity2);
}
}
#endregion
#region Protected Methods and Properties
protected override void PerformLoad(IDesignerSerializationManager serializationManager)
{
}
protected override void PerformFlush(IDesignerSerializationManager serializationManager)
{
SaveDesignerLayout();
}
protected override void OnEndLoad(bool successful, ICollection errors)
{
base.OnEndLoad(successful, errors);
if (successful)
{
//We initialize the events coordinator only once when loading of the designer is complete
ActivityDesigner rootDesigner = ActivityDesigner.GetRootDesigner(LoaderHost);
if (this.eventsCoordinator == null && (rootDesigner == null || rootDesigner.ParentDesigner == null))
this.eventsCoordinator = new WorkflowDesignerEventsCoordinator(LoaderHost);
try
{
this.loadingDesignerLayout = true;
string layoutFileName = DesignerLayoutFileName;
IList layoutErrors = null;
if (File.Exists(layoutFileName))
LoadDesignerLayout(out layoutErrors);
else if (InDebugMode || (ActivityDesigner.GetRootDesigner(LoaderHost) != null && ActivityDesigner.GetRootDesigner(LoaderHost).ParentDesigner != null))
LoadDesignerLayoutFromResource(out layoutErrors);
if (layoutErrors != null)
{
if (errors == null)
errors = new ArrayList();
IList designerErrors = errors as IList;
if (designerErrors != null)
{
foreach (object layoutError in layoutErrors)
designerErrors.Add(layoutError);
}
}
}
finally
{
this.loadingDesignerLayout = false;
}
}
}
protected void LoadDesignerLayoutFromResource(Type type, string manifestResourceName, out IList errors)
{
if (type == null)
throw new ArgumentNullException("type");
if (manifestResourceName == null)
throw new ArgumentNullException("manifestResourceName");
if (manifestResourceName.Length == 0)
throw new ArgumentException(SR.GetString(SR.Error_ParameterCannotBeEmpty), "manifestResourceName");
errors = new ArrayList();
Stream stream = type.Module.Assembly.GetManifestResourceStream(type, manifestResourceName);
if (stream == null)
stream = type.Module.Assembly.GetManifestResourceStream(manifestResourceName);
if (stream != null)
{
using (XmlReader layoutReader = XmlReader.Create(stream))
{
if (layoutReader != null)
LoadDesignerLayout(layoutReader, out errors);
}
}
}
protected void LoadDesignerLayout(XmlReader layoutReader, out IList layoutLoadErrors)
{
if (layoutReader == null)
throw new ArgumentNullException("layoutReader");
ArrayList errors = new ArrayList();
layoutLoadErrors = errors;
ActivityDesigner rootDesigner = null;
IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
if (designerHost != null && designerHost.RootComponent != null)
rootDesigner = designerHost.GetDesigner(designerHost.RootComponent) as ActivityDesigner;
if (rootDesigner != null)
{
if (rootDesigner.SupportsLayoutPersistence)
{
DesignerSerializationManager serializationManager = new DesignerSerializationManager(LoaderHost);
using (serializationManager.CreateSession())
{
WorkflowMarkupSerializationManager layoutSerializationManager = new WorkflowMarkupSerializationManager(serializationManager);
layoutSerializationManager.AddSerializationProvider(new ActivityDesignerLayoutSerializerProvider());
try
{
new WorkflowMarkupSerializer().Deserialize(layoutSerializationManager, layoutReader);
}
catch (Exception e)
{
errors.Add(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_LayoutDeserialization), e));
}
finally
{
if (serializationManager.Errors != null)
errors.AddRange(serializationManager.Errors);
}
}
}
else
{
errors.Add(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_LayoutSerializationPersistenceSupport)));
}
}
else
{
errors.Add(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_LayoutSerializationRootDesignerNotFound)));
}
}
protected void SaveDesignerLayout(XmlWriter layoutWriter, ActivityDesigner rootDesigner, out IList layoutSaveErrors)
{
if (layoutWriter == null)
throw new ArgumentNullException("layoutWriter");
if (rootDesigner == null)
throw new ArgumentNullException("rootDesigner");
ArrayList errors = new ArrayList();
layoutSaveErrors = errors;
if (rootDesigner.SupportsLayoutPersistence)
{
DesignerSerializationManager serializationManager = new DesignerSerializationManager(LoaderHost);
using (serializationManager.CreateSession())
{
WorkflowMarkupSerializationManager layoutSerializationManager = new WorkflowMarkupSerializationManager(serializationManager);
layoutSerializationManager.AddSerializationProvider(new ActivityDesignerLayoutSerializerProvider());
try
{
new WorkflowMarkupSerializer().Serialize(layoutSerializationManager, layoutWriter, rootDesigner);
}
catch (Exception e)
{
errors.Add(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_LayoutSerialization), e));
}
finally
{
if (serializationManager.Errors != null)
errors.AddRange(serializationManager.Errors);
}
}
}
else
{
errors.Add(new WorkflowMarkupSerializationException(SR.GetString(SR.Error_LayoutSerializationPersistenceSupport)));
}
}
#endregion
#region Private Methods and Properties
internal void SetModified(bool modified)
{
if (LoaderHost != null && !LoaderHost.Loading && !this.loadingDesignerLayout)
{
OnModifying();
base.Modified = modified;
}
}
internal static void AddActivityToDesigner(IServiceProvider serviceProvider, Activity activity)
{
WorkflowDesignerLoader workflowLoader = serviceProvider.GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader;
if (workflowLoader == null)
throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(WorkflowDesignerLoader).FullName));
workflowLoader.AddActivityToDesigner(activity);
}
internal static void RemoveActivityFromDesigner(IServiceProvider serviceProvider, Activity activity)
{
WorkflowDesignerLoader workflowLoader = serviceProvider.GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader;
if (workflowLoader == null)
throw new InvalidOperationException(SR.GetString(SR.General_MissingService, typeof(WorkflowDesignerLoader).FullName));
workflowLoader.RemoveActivityFromDesigner(activity);
}
private object OnCreateService(IServiceContainer container, Type serviceType)
{
object createdService = null;
if (serviceType == typeof(ComponentSerializationService))
createdService = new XomlComponentSerializationService(LoaderHost);
else if (serviceType == typeof(IReferenceService))
createdService = new ReferenceService(LoaderHost);
else if (serviceType == typeof(IIdentifierCreationService))
createdService = new IdentifierCreationService(container, this);
else if (serviceType == typeof(IWorkflowCompilerOptionsService))
createdService = new WorkflowCompilerOptionsService();
else if (serviceType == typeof(IDesignerVerbProviderService))
createdService = new DesignerVerbProviderService();
if (createdService != null)
{
if (this.createdServices == null)
this.createdServices = new Hashtable();
object existingService = this.createdServices[serviceType];
this.createdServices[serviceType] = createdService;
if (existingService != null)
{
OnDisposeService(serviceType, existingService);
}
}
return createdService;
}
private void OnDisposeService(Type serviceType, object service)
{
if (serviceType == typeof(IReferenceService))
{
ReferenceService refService = service as ReferenceService;
if (refService != null)
{
refService.Dispose();
}
}
}
private void LoadDesignerLayoutFromResource(out IList layoutErrors)
{
layoutErrors = null;
IWorkflowRootDesigner rootDesigner = ActivityDesigner.GetSafeRootDesigner(LoaderHost);
if (rootDesigner == null || !rootDesigner.SupportsLayoutPersistence)
return;
Type rootActivityType = rootDesigner.Component.GetType();
string resourceName = rootActivityType.Name + WorkflowDesignerLoader.DesignerLayoutFileExtension;
LoadDesignerLayoutFromResource(rootActivityType, resourceName, out layoutErrors);
}
private void LoadDesignerLayout(out IList layoutErrors)
{
layoutErrors = null;
string layoutFileName = DesignerLayoutFileName;
IWorkflowRootDesigner rootDesigner = ActivityDesigner.GetSafeRootDesigner(LoaderHost);
if (rootDesigner == null || !rootDesigner.SupportsLayoutPersistence || !File.Exists(layoutFileName))
return;
using (TextReader layoutReader = GetFileReader(layoutFileName))
{
if (layoutReader != null)
{
using (XmlReader xmlReader = XmlReader.Create(layoutReader))
LoadDesignerLayout(xmlReader, out layoutErrors);
}
}
}
private void SaveDesignerLayout()
{
string layoutFileName = DesignerLayoutFileName;
ActivityDesigner rootDesigner = ActivityDesigner.GetSafeRootDesigner(LoaderHost);
if (String.IsNullOrEmpty(layoutFileName) || rootDesigner == null || !rootDesigner.SupportsLayoutPersistence)
return;
using (TextWriter layoutWriter = GetFileWriter(layoutFileName))
{
if (layoutWriter != null)
{
IList layoutErrors = null;
using (XmlWriter xmlWriter = Helpers.CreateXmlWriter(layoutWriter))
SaveDesignerLayout(xmlWriter, rootDesigner, out layoutErrors);
}
}
}
private string DesignerLayoutFileName
{
get
{
string layoutFileName = FileName;
if (!String.IsNullOrEmpty(layoutFileName))
{
layoutFileName = Path.Combine(Path.GetDirectoryName(layoutFileName), Path.GetFileNameWithoutExtension(layoutFileName));
layoutFileName += WorkflowDesignerLoader.DesignerLayoutFileExtension;
}
return layoutFileName;
}
}
#endregion
}
#endregion
#region Class DesignerVerbProviderService
internal sealed class DesignerVerbProviderService : IDesignerVerbProviderService
{
private List<IDesignerVerbProvider> designerVerbProviders = new List<IDesignerVerbProvider>();
public DesignerVerbProviderService()
{
((IDesignerVerbProviderService)this).AddVerbProvider(new FreeFormDesignerVerbProvider());
}
#region IDesignerVerbProviderService Implementation
void IDesignerVerbProviderService.AddVerbProvider(IDesignerVerbProvider verbProvider)
{
if (!this.designerVerbProviders.Contains(verbProvider))
this.designerVerbProviders.Add(verbProvider);
}
void IDesignerVerbProviderService.RemoveVerbProvider(IDesignerVerbProvider verbProvider)
{
this.designerVerbProviders.Remove(verbProvider);
}
ReadOnlyCollection<IDesignerVerbProvider> IDesignerVerbProviderService.VerbProviders
{
get
{
return this.designerVerbProviders.AsReadOnly();
}
}
#endregion
}
#endregion
#region Class WorkflowDesignerEventsCoordinator
//THIS CLASS IS CREATED WITH SOLE PURPOSE OF LISTENING TO COMMON EVENTS AT ONE LOCATION, AND AVOID
//LISTENING TO EVENTS SUCH AS TYPESCHANGED, ACTIVEDESIGNERCHANGED, SELECTIONCHANGED AND COMPONENTCHANGED
//REPEATEDLY
internal sealed class WorkflowDesignerEventsCoordinator : IDisposable
{
private IDesignerLoaderHost serviceProvider;
private bool typeSystemTypesChanged = false;
private EventHandler refreshTypesHandler;
private EventHandler refreshDesignerActionsHandler;
private EventHandler refreshTasksHandler;
public WorkflowDesignerEventsCoordinator(IDesignerLoaderHost serviceProvider)
{
this.serviceProvider = serviceProvider;
this.serviceProvider.LoadComplete += new EventHandler(OnDesignerReloaded);
//Listen to the events so that we are sure that we appropriately refresh the designer actions and tasks when the types
//change
IDesignerEventService designerEventService = this.serviceProvider.GetService(typeof(IDesignerEventService)) as IDesignerEventService;
if (designerEventService != null)
designerEventService.ActiveDesignerChanged += new ActiveDesignerEventHandler(OnActiveDesignerChanged);
ITypeProvider typeProvider = this.serviceProvider.GetService(typeof(ITypeProvider)) as ITypeProvider;
if (typeProvider != null)
typeProvider.TypesChanged += new EventHandler(OnTypeSystemTypesChanged);
ISelectionService selectionService = this.serviceProvider.GetService(typeof(ISelectionService)) as ISelectionService;
if (selectionService != null)
selectionService.SelectionChanged += new EventHandler(OnSelectionChanged);
IComponentChangeService componentChangedService = this.serviceProvider.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
if (componentChangedService != null)
componentChangedService.ComponentChanged += new ComponentChangedEventHandler(OnComponentChanged);
IPropertyValueUIService propertyValueService = this.serviceProvider.GetService(typeof(IPropertyValueUIService)) as IPropertyValueUIService;
if (propertyValueService != null)
propertyValueService.AddPropertyValueUIHandler(new PropertyValueUIHandler(OnPropertyGridAdornments));
}
void IDisposable.Dispose()
{
WorkflowView workflowView = this.serviceProvider.GetService(typeof(WorkflowView)) as WorkflowView;
if (workflowView != null)
{
if (this.refreshTypesHandler != null)
workflowView.Idle -= this.refreshTypesHandler;
if (this.refreshDesignerActionsHandler != null)
workflowView.Idle -= this.refreshDesignerActionsHandler;
if (this.refreshTasksHandler != null)
workflowView.Idle -= this.refreshTasksHandler;
}
this.refreshTypesHandler = null;
this.refreshDesignerActionsHandler = null;
this.refreshTasksHandler = null;
IExtendedUIService extUIService = this.serviceProvider.GetService(typeof(IExtendedUIService)) as IExtendedUIService;
if (extUIService != null)
extUIService.RemoveDesignerActions();
IPropertyValueUIService propertyValueService = this.serviceProvider.GetService(typeof(IPropertyValueUIService)) as IPropertyValueUIService;
if (propertyValueService != null)
propertyValueService.RemovePropertyValueUIHandler(new PropertyValueUIHandler(OnPropertyGridAdornments));
IComponentChangeService componentChangedService = this.serviceProvider.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
if (componentChangedService != null)
componentChangedService.ComponentChanged -= new ComponentChangedEventHandler(OnComponentChanged);
ISelectionService selectionService = this.serviceProvider.GetService(typeof(ISelectionService)) as ISelectionService;
if (selectionService != null)
selectionService.SelectionChanged -= new EventHandler(OnSelectionChanged);
ITypeProvider typeProvider = this.serviceProvider.GetService(typeof(ITypeProvider)) as ITypeProvider;
if (typeProvider != null)
typeProvider.TypesChanged -= new EventHandler(OnTypeSystemTypesChanged);
IDesignerEventService designerEventService = this.serviceProvider.GetService(typeof(IDesignerEventService)) as IDesignerEventService;
if (designerEventService != null)
designerEventService.ActiveDesignerChanged -= new ActiveDesignerEventHandler(OnActiveDesignerChanged);
this.serviceProvider.LoadComplete -= new EventHandler(OnDesignerReloaded);
}
private void OnDesignerReloaded(object sender, EventArgs e)
{
bool refreshTypes = (this.refreshTypesHandler != null);
bool refreshDesignerActions = (this.refreshDesignerActionsHandler != null);
bool refreshTasks = (this.refreshTasksHandler != null);
this.refreshTypesHandler = null;
this.refreshDesignerActionsHandler = null;
this.refreshTasksHandler = null;
if (refreshTypes || refreshTasks || refreshDesignerActions)
{
RefreshTypes();
RefreshDesignerActions();
}
}
private void OnTypeSystemTypesChanged(object sender, EventArgs e)
{
this.typeSystemTypesChanged = true;
//If the current designer is not active designer then we need to wait for it to be active before we update the types
IDesignerEventService designerEventService = this.serviceProvider.GetService(typeof(IDesignerEventService)) as IDesignerEventService;
if (designerEventService != null && designerEventService.ActiveDesigner == this.serviceProvider.GetService(typeof(IDesignerHost)))
RefreshTypes();
}
private void OnActiveDesignerChanged(object sender, ActiveDesignerEventArgs e)
{
if (e.NewDesigner == this.serviceProvider.GetService(typeof(IDesignerHost)) && this.typeSystemTypesChanged)
RefreshTypes();
else
RefreshTasks();
}
private void OnComponentChanged(object sender, ComponentChangedEventArgs eventArgs)
{
RefreshDesignerActions();
}
private void RefreshTypes()
{
if (this.refreshTypesHandler == null && this.typeSystemTypesChanged)
{
WorkflowView workflowView = this.serviceProvider.GetService(typeof(WorkflowView)) as WorkflowView;
if (workflowView != null)
{
this.refreshTypesHandler = new EventHandler(OnRefreshTypes);
workflowView.Idle += this.refreshTypesHandler;
}
}
this.typeSystemTypesChanged = false;
}
private void OnRefreshTypes(object sender, EventArgs e)
{
if (this.refreshTypesHandler != null)
{
WorkflowView workflowView = this.serviceProvider.GetService(typeof(WorkflowView)) as WorkflowView;
if (workflowView != null)
workflowView.Idle -= this.refreshTypesHandler;
this.refreshTypesHandler = null;
}
IDesignerHost designerHost = this.serviceProvider.GetService(typeof(IDesignerHost)) as IDesignerHost;
Activity rootActivity = (designerHost != null) ? designerHost.RootComponent as Activity : null;
if (rootActivity == null)
return;
//Now Refresh the types as well as the designer actions
ITypeProvider typeProvider = this.serviceProvider.GetService(typeof(ITypeProvider)) as ITypeProvider;
if (typeProvider != null)
{
Walker walker = new Walker();
walker.FoundProperty += delegate(Walker w, WalkerEventArgs args)
{
if (args.CurrentValue != null &&
args.CurrentProperty != null &&
args.CurrentProperty.PropertyType == typeof(System.Type) &&
args.CurrentValue is System.Type)
{
Type updatedType = typeProvider.GetType(((Type)args.CurrentValue).FullName);
if (updatedType != null)
{
args.CurrentProperty.SetValue(args.CurrentPropertyOwner, updatedType, null);
if (args.CurrentActivity != null)
TypeDescriptor.Refresh(args.CurrentActivity);
}
}
else if (args.CurrentProperty == null && args.CurrentValue is DependencyObject && !(args.CurrentValue is Activity))
{
walker.WalkProperties(args.CurrentActivity, args.CurrentValue);
}
};
walker.FoundActivity += delegate(Walker w, WalkerEventArgs args)
{
if (args.CurrentActivity != null)
{
TypeDescriptor.Refresh(args.CurrentActivity);
ActivityDesigner activityDesigner = ActivityDesigner.GetDesigner(args.CurrentActivity);
if (activityDesigner != null)
activityDesigner.RefreshDesignerActions();
InvokeWorkflowDesigner invokeWorkflowDesigner = activityDesigner as InvokeWorkflowDesigner;
if (invokeWorkflowDesigner != null)
invokeWorkflowDesigner.RefreshTargetWorkflowType();
}
};
walker.Walk(rootActivity);
}
IPropertyValueUIService propertyValueService = this.serviceProvider.GetService(typeof(IPropertyValueUIService)) as IPropertyValueUIService;
if (propertyValueService != null)
propertyValueService.NotifyPropertyValueUIItemsChanged();
RefreshTasks();
RefreshDesignerActions();
}
private void RefreshDesignerActions()
{
if (this.refreshDesignerActionsHandler == null)
{
WorkflowView workflowView = this.serviceProvider.GetService(typeof(WorkflowView)) as WorkflowView;
if (workflowView != null)
{
this.refreshDesignerActionsHandler = new EventHandler(OnRefreshDesignerActions);
workflowView.Idle += this.refreshDesignerActionsHandler;
}
}
}
private void OnRefreshDesignerActions(object sender, EventArgs e)
{
//NOTE: Make sure that we dont invalidate the workflow here. Workflow will be invalidated when'
//the designer actions are refreshed on idle thread. Putting invalidation logic here causes the validation
//to go haywire as before the idle message comes in we start getting to DesignerActions thru the paiting
//logic to show smart tags. This causes problems and ConfigErrors appear everywhere on designer intermittently
//PROBLEM: ConfigErrors appearing on the entire design surface
//This is due to a race condition between the validation triggered during painting
//logic and validation triggered when we try to access the DesignerActions from RefreshTask handler
//In the validation logic we try to get to the types while doing so we Refresh the code compile unit
//in typesystem which in turn triggers CodeDomLoader.Refresh. In this we remove types, call refresh handler
//and add new types. While doing this after the remove types but before addtypes, call is made to the drawing
//logic in which we try to grab the designer actions which triggers another set of validations hence now we
//always call UpdateWindow after invalidatewindow so that the validation will always get triggered on painting thread.
//NOTE: PLEASE DO NOT CHANGE SEQUENCE IN WHICH THE FOLLOWING HANDLERS ARE ADDED
//THE PROBLEM CAN BE ALSO FIXED BY TRIGGERING VALIDATION IN RefreshDesignerActions ITSELF
//FOR NOW THE REFRESH FIX WILL CAUSE MINIMAL IMPACT IN THE LIGHT OF M3
WorkflowView workflowView = this.serviceProvider.GetService(typeof(WorkflowView)) as WorkflowView;
if (this.refreshDesignerActionsHandler != null)
{
if (workflowView != null)
workflowView.Idle -= this.refreshDesignerActionsHandler;
this.refreshDesignerActionsHandler = null;
}
DesignerHelpers.RefreshDesignerActions(this.serviceProvider);
IPropertyValueUIService propertyValueService = this.serviceProvider.GetService(typeof(IPropertyValueUIService)) as IPropertyValueUIService;
if (propertyValueService != null)
propertyValueService.NotifyPropertyValueUIItemsChanged();
RefreshTasks();
}
private void OnSelectionChanged(object sender, EventArgs e)
{
WorkflowView workflowView = this.serviceProvider.GetService(typeof(WorkflowView)) as WorkflowView;
if (workflowView != null)
workflowView.Invalidate();
RefreshTasks();
}
private void RefreshTasks()
{
if (this.refreshTasksHandler == null)
{
//Listen to the next idle event to populate the tasks; this should happen on selection changed as well as active designer changed if the current designer is active
WorkflowView workflowView = this.serviceProvider.GetService(typeof(WorkflowView)) as WorkflowView;
if (workflowView != null)
{
this.refreshTasksHandler = new EventHandler(OnRefreshTasks);
workflowView.Idle += this.refreshTasksHandler;
}
}
}
private void OnRefreshTasks(object sender, EventArgs e)
{
WorkflowView workflowView = this.serviceProvider.GetService(typeof(WorkflowView)) as WorkflowView;
if (this.refreshTasksHandler != null)
{
if (workflowView != null)
workflowView.Idle -= this.refreshTasksHandler;
this.refreshTasksHandler = null;
}
ISelectionService selectionService = this.serviceProvider.GetService(typeof(ISelectionService)) as ISelectionService;
IExtendedUIService extendedUIService = this.serviceProvider.GetService(typeof(IExtendedUIService)) as IExtendedUIService;
if (selectionService != null && extendedUIService != null)
{
extendedUIService.RemoveDesignerActions();
//Only if the current designer is active designer we add the designer actions to the task list
IDesignerEventService designerEventService = (IDesignerEventService)this.serviceProvider.GetService(typeof(IDesignerEventService));
if (designerEventService != null && designerEventService.ActiveDesigner == this.serviceProvider.GetService(typeof(IDesignerHost)))
{
foreach (object obj in selectionService.GetSelectedComponents())
{
ActivityDesigner activityDesigner = null;
if (obj is HitTestInfo)
activityDesigner = ((HitTestInfo)obj).AssociatedDesigner;
else if (obj is Activity)
activityDesigner = ActivityDesigner.GetDesigner(obj as Activity);
if (activityDesigner != null)
extendedUIService.AddDesignerActions(new List<DesignerAction>(activityDesigner.DesignerActions).ToArray());
}
}
}
if (workflowView != null)
workflowView.Invalidate();
}
private void OnPropertyGridAdornments(ITypeDescriptorContext context, PropertyDescriptor propDesc, ArrayList valueUIItemList)
{
IComponent component = null;
IReferenceService referenceService = this.serviceProvider.GetService(typeof(IReferenceService)) as IReferenceService;
if (referenceService != null)
component = referenceService.GetComponent(context.Instance);
string fullAliasName = string.Empty;
//this attribue is set to overcome issue with the TypedVariableDeclarationTypeConverter
//not returning Name property at all. we alias that property to the VariableDeclaration itself
DefaultPropertyAttribute aliasPropertyNameAttribute = propDesc.Attributes[typeof(DefaultPropertyAttribute)] as DefaultPropertyAttribute;
if (aliasPropertyNameAttribute != null && aliasPropertyNameAttribute.Name != null && aliasPropertyNameAttribute.Name.Length > 0)
fullAliasName = propDesc.Name + "." + aliasPropertyNameAttribute.Name;
if (component != null)
{
ActivityDesigner activityDesigner = ActivityDesigner.GetDesigner(component as Activity);
if (activityDesigner != null)
{
if (!activityDesigner.IsLocked && ActivityBindPropertyDescriptor.IsBindableProperty(propDesc) && !propDesc.IsReadOnly)
valueUIItemList.Add(new PropertyValueUIItem(DR.GetImage(DR.Bind), OnBindProperty, DR.GetString(DR.BindProperty)));
string fullComponentName = referenceService.GetName(component); //schedule1.send1
string fullPropertyName = referenceService.GetName(context.Instance); //schedule1.send1.message
fullPropertyName = (fullPropertyName.Length > fullComponentName.Length) ? fullPropertyName.Substring(fullComponentName.Length + 1, fullPropertyName.Length - fullComponentName.Length - 1) + "." + propDesc.Name : string.Empty;
foreach (DesignerAction action in activityDesigner.DesignerActions)
{
string actionPropertyName = action.PropertyName as string;
if (actionPropertyName == null || actionPropertyName.Length == 0)
continue;
if (actionPropertyName == propDesc.Name || (actionPropertyName == fullPropertyName) || (actionPropertyName == fullAliasName))
{
PropertyValueUIItemHandler propValueUIItemhandler = new PropertyValueUIItemHandler(action);
valueUIItemList.Add(new PropertyValueUIItem(action.Image, propValueUIItemhandler.OnFixPropertyError, action.Text));
break;
}
}
}
}
}
private void OnBindProperty(ITypeDescriptorContext context, PropertyDescriptor descriptor, PropertyValueUIItem invokedItem)
{
BindUITypeEditor.EditValue(context);
}
#region Class PropertyValueUIItemHandler
private class PropertyValueUIItemHandler
{
DesignerAction action = null;
internal PropertyValueUIItemHandler(DesignerAction action)
{
this.action = action;
}
internal void OnFixPropertyError(ITypeDescriptorContext context, PropertyDescriptor descriptor, PropertyValueUIItem invokedItem)
{
action.Invoke();
}
}
#endregion
}
#endregion
}
|