NullReferenceException in ReHosted Designer on double-click
-
Friday, July 30, 2010 3:52 PM
Hi,
I have a WinForms application with a rehosted workflow designer (WF4) and although my xamlx workflow opens in the designer without error, I find that when I drill down into the SendReceive activities I get a NullReferenceException as follows:
NullReferenceException: Object reference not set to an instance of an object, at
System.Activities.Core.Presentation.FlowchartDesigner.CleanupFlowchart()
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)...
I'm running on Windows 7 x64.
Any help with this would be hugely appreciated.
Thanks,
Stuart
All Replies
-
Friday, July 30, 2010 5:17 PMcan you paste me your repro code so I can investigate?
-
Monday, August 02, 2010 9:00 AM
There's a lot of code to paste, in here, but I'll give it a go :o) What I've pasted below is the code for the workflow designer. What it does is in the LoadWorkflow method it receives a path to a .xamlx file which is then loaded into the designer. I do also have a tracking feature which takes the peristed tracking records and shows the history of the workflow and where the workflow currently is, however I get the exception without even running through the tracking code.
My apologies for the untidyness of the code but it's very much a work in progress. Would the .xamlx file be of help? It's basically a flowchart with a number of SendReceives and some variable assignments.
Thanks,
Stuart
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Activities.Core.Presentation; using System.Activities.Presentation; using System.Activities.Statements; using System.Activities.Presentation.Model; using System.Activities.Presentation.Services; using System.Activities.Presentation.View; using System.Activities.Presentation.Debug; using System.Reflection; using System.Xaml; using System.Activities.Tracking; using DT.Imago.Entities.WorkManagement; using System.Activities.Debugger; using System.Windows.Threading; using System.Activities; using System.Activities.XamlIntegration; using DT.Imago.WorkManagement.ActivityLibrary; using System.Windows.Markup; using System.IO; using System.Windows.Resources; using System.ComponentModel; namespace DT.Imago.Admin.WorkManagement.WPFDesigner { /// <summary> /// Interaction logic for WPFWorkflowDesigner.xaml /// </summary> public partial class WPFWorkflowDesigner : UserControl { private WorkflowDesigner mWorkflowDesigner; private IDesignerDebugView mDesignDebugView; private DebuggerService mDebuggerService; private string mXamlPath; private System.ServiceModel.Activities.WorkflowService mWFService; private AttachedProperty<Visibility> mAttachProp = null; private AttachedProperty<Visibility> mAttachPropTipShow = null; private AttachedProperty<string> mAttachPropTip = null; public WPFWorkflowDesigner() { InitializeComponent(); } protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); StreamResourceInfo sri = System.Windows.Application.GetResourceStream(new Uri("/WorkManagement/WPFDesigner/CustomWorkflowElementDesignerTemplate.xaml", UriKind.Relative)); ResourceDictionary resources = (ResourceDictionary)BamlReader.Load(sri.Stream); foreach (object key in resources.Keys) { Resources.Add(key, resources[key]); } Style activityDesignerStyle = (Style)Resources[typeof(ActivityDesigner)]; foreach (Type activityDesignerType in typeof(System.Activities.Core.Presentation.DesignerMetadata).Assembly.GetTypes()) { if (typeof(ActivityDesigner).IsAssignableFrom(activityDesignerType)) { Resources[activityDesignerType] = activityDesignerStyle; } } // register metadata (new DesignerMetadata()).Register(); // create the workflow designer mWorkflowDesigner = new WorkflowDesigner(); mDesignDebugView = mWorkflowDesigner.DebugManagerView; mAttachProp = new AttachedProperty<Visibility>() { Name = "Show", Getter = (modelItem) => ShowExecute.IsExist(modelItem), Setter = (modelItem, show) => ShowExecute.Add(modelItem), OwnerType = typeof(Activity) }; //Attached Property for portions of the Designer that would be seen only when the activity has not finished execution mAttachPropTipShow = new AttachedProperty<Visibility>() { Name = "UnShow", Getter = (modelItem) => ShowExecute.IsNonExist(modelItem), OwnerType = typeof(Activity) }; //Attached Property for the tool tip Text about when the activity finished execution mAttachPropTip = new AttachedProperty<string>() { Name = "TipText", Getter = (modelItem) => ShowExecute.GetTime(modelItem), OwnerType = typeof(Activity) }; } public void LoadWorkflow(string instance) { mXamlPath = instance; mWFService = XamlServices.Load(instance) as System.ServiceModel.Activities.WorkflowService; //Adding the attached properties to the designer. this.mWorkflowDesigner.Context.Services.GetService<AttachedPropertiesService>().AddProperty(mAttachProp); this.mWorkflowDesigner.Context.Services.GetService<AttachedPropertiesService>().AddProperty(mAttachPropTipShow); this.mWorkflowDesigner.Context.Services.GetService<AttachedPropertiesService>().AddProperty(mAttachPropTip); mWorkflowDesigner.Load(mXamlPath); this.DesignerBorder.Child = mWorkflowDesigner.View; //DisableProperties //this.PropertyBorder.Child = mWorkflowDesigner.PropertyInspectorView; mDebuggerService = new DebuggerService(mWorkflowDesigner.Context); } public void RunTracking(WFTrackingRecordSummary[] trackingRecords) { List<ActivityStateRecord> activityStateRecords = ConvertTrackingRecordsToActivityStateRecords(trackingRecords); //Mapping between the Object and Line No. Dictionary<object, SourceLocation> wfElementToSourceLocationMap = UpdateSourceLocationMappingInDebuggerService(); //Mapping between the Object and the Instance Id Dictionary<string, Activity> activityIdToWfElementMap = BuildActivityIdToWfElementMap(wfElementToSourceLocationMap); activityStateRecords.Sort(delegate(ActivityStateRecord s1, ActivityStateRecord s2) { return s1.RecordNumber.CompareTo(s2.RecordNumber); }); ModelService modelService = mWorkflowDesigner.Context.Services.GetService<ModelService>(); IEnumerable<ModelItem> modelItems = modelService.Find(modelService.Root, typeof(Object)); foreach (ActivityStateRecord activityStateRecord in activityStateRecords) { bool debugExecuted = false; Activity trackingActivity = activityIdToWfElementMap[activityStateRecord.Activity.Id]; if (trackingActivity != null) { if (modelService != null) { foreach (ModelItem modelItem in modelItems) { if ((TypeDescriptor.GetProperties(modelItem)["Show"] != null) && modelItem.Parent.Content != null && TypeDescriptor.GetProperties(modelItem.Parent.Content.ComputedValue)["DisplayName"] != null && TypeDescriptor.GetProperties(modelItem.Parent.Content.ComputedValue)["DisplayName"].GetValue(modelItem.Parent.Content.ComputedValue).ToString() == trackingActivity.DisplayName) { this.Dispatcher.Invoke(DispatcherPriority.Render , (Action)(() => { if (TypeDescriptor.GetProperties(modelItem)["Show"] != null) { TypeDescriptor.GetProperties(modelItem)["Show"].SetValue(modelItem, Visibility.Visible); //TypeDescriptor.GetProperties(modelItem)["UnShow"].GetValue(modelItem); //mAttachPropTipShow.NotifyPropertyChanged(modelItem); mAttachProp.NotifyPropertyChanged(modelItem); } })); } if (modelItem.Content != null && TypeDescriptor.GetProperties(modelItem.Content.ComputedValue)["DisplayName"] != null && TypeDescriptor.GetProperties(modelItem.Content.ComputedValue)["DisplayName"].GetValue(modelItem.Content.ComputedValue).ToString() == trackingActivity.DisplayName) { ShowDebug(wfElementToSourceLocationMap[trackingActivity], modelItem); debugExecuted = true; //break; } } if (!debugExecuted) ShowDebug(wfElementToSourceLocationMap[trackingActivity], null); } } } } private List<ActivityStateRecord> ConvertTrackingRecordsToActivityStateRecords(WFTrackingRecordSummary[] trackingRecords) { List<ActivityStateRecord> activityStateRecords = new List<ActivityStateRecord>(); foreach (WFTrackingRecordSummary trackingRecord in trackingRecords) { ActivityInfo activity = new ActivityInfo(trackingRecord.ActivityName, trackingRecord.ActivityID, trackingRecord.ActivityInstanceID, trackingRecord.ActivityType); ActivityStateRecord activityStateRecord = new ActivityStateRecord(trackingRecord.WorkflowInstanceID, long.Parse(trackingRecord.RecordNumber.Value.ToString()), activity, trackingRecord.State); //activityStateRecord.Level = //activityStateRecord.Arguments = DeSerializeData<string, object>(trackingRecord.ArgumentsXml); //activityStateRecord.Variables = DeSerializeData<string, object>(trackingRecord.VariablesXml); //activityStateRecord.Annotations = DeSerializeData<string, string>(trackingRecord.AnnotationsXml); //activityStateRecord.EventTime = trackingRecord.TimeCreated.Value; activityStateRecords.Add(activityStateRecord); } return activityStateRecords; } void ShowDebug(SourceLocation srcLoc, ModelItem modelItem) { this.Dispatcher.Invoke(DispatcherPriority.Render , (Action)(() => { mWorkflowDesigner.DebugManagerView.CurrentLocation = srcLoc; if (modelItem != null) { Selection selection = new Selection(modelItem); mWorkflowDesigner.Context.Items.SetValue(selection); } ModelItem mi = this.mWorkflowDesigner.Context.Items.GetValue<Selection>().PrimarySelection; if (mi != null && TypeDescriptor.GetProperties(mi)["Show"] != null) { TypeDescriptor.GetProperties(mi)["Show"].SetValue(mi, Visibility.Visible); mAttachProp.NotifyPropertyChanged(mi); } })); } Dictionary<object, SourceLocation> UpdateSourceLocationMappingInDebuggerService() { object rootInstance = GetRootInstance(); Dictionary<object, SourceLocation> sourceLocationMapping = new Dictionary<object, SourceLocation>(); Dictionary<object, SourceLocation> designerSourceLocationMapping = new Dictionary<object, SourceLocation>(); if (rootInstance != null) { Activity documentRootElement = GetRootWorkflowElement(rootInstance); SourceLocationProvider.CollectMapping(GetRootRuntimeWorkflowElement(), documentRootElement, sourceLocationMapping, mWorkflowDesigner.Context.Items.GetValue<WorkflowFileItem>().LoadedFile); SourceLocationProvider.CollectMapping(documentRootElement, documentRootElement, designerSourceLocationMapping, mWorkflowDesigner.Context.Items.GetValue<WorkflowFileItem>().LoadedFile); } // Notify the DebuggerService of the new sourceLocationMapping. // When rootInstance == null, it'll just reset the mapping. //DebuggerService debuggerService = debuggerService as DebuggerService; if (mDebuggerService != null) { ((DebuggerService)mDebuggerService).UpdateSourceLocations(designerSourceLocationMapping); } return sourceLocationMapping; } private Dictionary<string, Activity> BuildActivityIdToWfElementMap(Dictionary<object, SourceLocation> wfElementToSourceLocationMap) { Dictionary<string, Activity> map = new Dictionary<string, Activity>(); Activity wfElement; foreach (object instance in wfElementToSourceLocationMap.Keys) { wfElement = instance as Activity; if (wfElement != null) { map.Add(wfElement.Id, wfElement); } } return map; } # region Helper Methods object GetRootInstance() { ModelService modelService = mWorkflowDesigner.Context.Services.GetService<ModelService>(); if (modelService != null) { return modelService.Root.GetCurrentValue(); } else { return null; } } // Get root WorkflowElement. Currently only handle when the object is ActivitySchemaType or WorkflowElement. // May return null if it does not know how to get the root activity. Activity GetRootWorkflowElement(object rootModelObject) { System.Diagnostics.Debug.Assert(rootModelObject != null, "Cannot pass null as rootModelObject"); Activity rootWorkflowElement; IDebuggableWorkflowTree debuggableWorkflowTree = rootModelObject as IDebuggableWorkflowTree; if (debuggableWorkflowTree != null) { rootWorkflowElement = debuggableWorkflowTree.GetWorkflowRoot(); } else // Loose xaml case. { rootWorkflowElement = rootModelObject as Activity; } return rootWorkflowElement; } /*Activity GetRuntimeExecutionRoot() { Activity root = ActivityXamlServices.Load("Workflow.xaml"); WorkflowInspectionServices.CacheMetadata(root); return root; } */ Activity GetRootRuntimeWorkflowElement() { Activity root = mWFService.GetWorkflowRoot(); WorkflowInspectionServices.CacheMetadata(root); IEnumerator<Activity> enumerator1 = WorkflowInspectionServices.GetActivities(root).GetEnumerator(); //Get the first child of the x:class //avoid any literals and find the true root object while (enumerator1.MoveNext()) { if (enumerator1.Current.Equals("1.1")) { root = enumerator1.Current; break; } } return root; } # endregion } public static class ExtensionMethodsWPFWorkflowDesigner { private static Action EmptyDelegate = delegate() { }; public static void Refresh(this UIElement uiElement) { uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate); } } //Helper Class for the Attched Properties on the Model Items static class ShowExecute { static Dictionary<ModelItem, string> mySet = new Dictionary<ModelItem, string>(); internal static Visibility IsExist(ModelItem myItem) { foreach (ModelItem m in mySet.Keys) { if (m == myItem) { return Visibility.Visible; } } return Visibility.Hidden; } internal static Visibility IsNonExist(ModelItem myItem) { foreach (ModelItem m in mySet.Keys) { if (m == myItem) { return Visibility.Hidden; } } return Visibility.Visible; } internal static void Add(ModelItem myItem) { bool modelItemExists = false; foreach (ModelItem m in mySet.Keys) { if (m == myItem) { modelItemExists = true; break; } } if (modelItemExists) { mySet.Remove(myItem); } mySet.Add(myItem, DateTime.Now.ToLongTimeString()); } internal static string GetTime(ModelItem myItem) { foreach (ModelItem m in mySet.Keys) { if (m == myItem) { return mySet[myItem]; } } return "Never Executed"; } } internal static class BamlReader { public static object Load(Stream stream) { ParserContext pc = new ParserContext(); MethodInfo loadBamlMethod = typeof(System.Windows.Markup.XamlReader).GetMethod("LoadBaml", BindingFlags.NonPublic | BindingFlags.Static); return loadBamlMethod.Invoke(null, new object[] { stream, pc, null, false }); } } }
-
Monday, August 02, 2010 6:00 PM
thanks for your repro steps/
I will take a look today and return you the result tomorrow.
-
Tuesday, August 03, 2010 6:08 PM
I had a try on your code, but I can't repro.
can you paste me your xaml content?
-
Wednesday, August 04, 2010 7:46 AM
Hi,
I managed to narrow the problem down to the CustomWorkflowElementDesignerTemplate.xaml resource dictionary which I grabbed from Kushal Shah's example "VisualTrackingWithStepService". It seems that the resource dictionary loads fine for the first level of the workflow but when you double-click on any of the ReceiveSend activities and drill down you get a null reference exception presumably because the loaded resources have moved out of scope. I tried DrWPF's solution of loading the resources into the Application.Current.Resources.MergedDictionaries as shown below, but although the resources load I end up not having any activities rendered even at the top level, I just end up seeing an empty designer!
if (Application.Current == null) { // create the Application object new Application(); // merge in your application resources Application.Current.Resources.MergedDictionaries.Add( Application.LoadComponent( new Uri("/WorkManagement/WPFDesigner/CustomWorkflowElementDesignerTemplate.xaml", UriKind.Relative)) as ResourceDictionary); }
This problem is easy to solve in a WPF application because you simply reference the resource dictionary and style in the App.xaml but it's driving me nuts in my WinForms app...
I appreciate you taking the time to look at this.
Thanks,
Stuart
-
Friday, August 06, 2010 8:17 AM
Has anyone got any further thoughts on this?- Proposed As Answer by MirekSk Wednesday, September 08, 2010 2:51 PM
-
Wednesday, September 08, 2010 3:02 PM
hi,I'm working on some project using rehosted designer and have similar problem.When I add flowchart activity to designer and then close designer window, application throws an exception.Here is my callstack:
Build number: Developer buildOS version: Microsoft Windows NT 6.1.7600.0--- Type ---System.NullReferenceException--- Source ---System.Activities.Core.Presentation--- Message ---Object reference not set to an instance of an object.--- Callstack ---at System.Activities.Core.Presentation.FlowchartDesigner.CleanupFlowchart()at System.Activities.Core.Presentation.FlowchartDesigner.OnFreeFormPanelUnLoaded(Object sender, RoutedEventArgs eventArgs)at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)at System.Windows.BroadcastEventHelper.BroadcastUnloadedEvent(Object root)at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
My (part of) code:public class EditorViewModel : ViewModelBase { private ValidationErrorService _validation; private SaveProcessView _saveWindow; private WorkflowDesigner _workflowDesigner; private IEnumerable<ModelItem> _prevoriousItems = new List<ModelItem>(); private ModelItem _lastDroppedActivity; private BOMethod _lastdraggedMethod; private IProcessEditorView EditorView { get { return View as IProcessEditorView; } } private BusinessLayer.Interfaces.Workflow _workflow; private bool _saved; private readonly string _tempRunFile = Guid.NewGuid() + ".xaml"; public static string TmpFile = "tmp.xaml"; public List<EventTypeInfoList> ChangesStartupEventList = new List<EventTypeInfoList>(); #region ctors public EditorViewModel() { } [InjectionConstructor] public EditorViewModel(IProcessEditorView view, IUnityContainer unityContainer) : base(view, unityContainer) { new DesignerMetadata().Register(); RegisterCustomMetadata(); } #endregion private void Init(bool process) { _workflowDesigner = new WorkflowDesigner(); SubscribeValidationService(); if (!process) { var startConfig = new NewProcessView(); startConfig.ShowDialog(); //startConfig.ProcessType; //if (startConfig.StartActivity == null) { Close(); return; } var builder = new ActivityBuilder() { Name = "Workflow", Implementation = startConfig.StartActivity}; builder.Properties.Add(new DynamicActivityProperty() { Name = "Descriptions", Type = typeof(Dictionary<string,string>), Value = new Dictionary<string,string>() }); _workflowDesigner.Load(builder); ToggleButton btn = (ToggleButton)typeof(DesignerView).InvokeMember("buttonArguments1", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic, null, _workflowDesigner.Context.Services.GetService<DesignerView>(), null); btn.Visibility = Visibility.Collapsed; } else { _workflowDesigner.Load(_tempRunFile); } _workflowDesigner.ModelChanged += (e, v) => { OnPropertyChanged("ModelItemList"); EditorView.SetProjectStructureItems(ModelItemList); EditorView.RefreshProjectStructure(); _saved = false; }; _workflowDesigner.ModelChanged += (e, s) => DDOnModelChanged(); WorkflowView(); PropertyInspector(); ToolBox(); BusinessObjectList(); FindLastAddedItem(); EditorView.SetProjectStructureItems(ModelItemList); } private void SubscribeValidationService() { _validation = new ValidationErrorService(this); _workflowDesigner.Context.Services.Publish<IValidationErrorService>(_validation); } public override void OnClose() { File.Delete(_tempRunFile); EditorView.SerializeToolBox(); } public void Initialize(BusinessLayer.Interfaces.Workflow workflow = null) { var process = false; if (workflow != null) { View.ViewTitle = workflow.Name; _workflow = workflow; var wdp = ServiceFactory.Instance.GetService<IWorkflowDefinitionProvider>(); var wd = wdp.GetLastWorkflowDefinition(workflow.Id); workflow.Definition.Data = wd.Data; var fr = new FileStream(_tempRunFile, FileMode.Create, FileAccess.Write); fr.Write(wd.Data, 0, wd.Data.Length); fr.Close(); process = true; _saved = true; _saveWindow = new SaveProcessView(MonitService); if (_saveWindow.DataContext != null) ((SaveProcessViewModel)_saveWindow.DataContext).Workflow = workflow; } Init(process); } private void ToolBox() { EditorView.AddActivityDragHandler(ActivityItemDrag); EditorView.ConfigureToolBox(); } public void RefreshIcons() { RefreshCommands(); } private void PropertyInspector() { EditorView.SetPropertiesControl(_workflowDesigner.PropertyInspectorView); } private void WorkflowView() { EditorView.SetEditor(_workflowDesigner.View); } private void RegisterCustomMetadata() { var builder = new AttributeTableBuilder(); builder.AddCustomAttributes(typeof(MySequence), new DesignerAttribute(typeof(MySequenceDesigner))); builder.AddCustomAttributes(typeof(If),new DesignerAttribute(typeof(IfElseDesigner))); MetadataStore.AddAttributeTable(builder.CreateTable()); } public List<ModelItem> ModelItemList { get { var mi = _workflowDesigner.Context.Services.GetService<ModelService>().Root.Properties["Implementation"]; return new List<ModelItem> { (mi != null) ? mi.Value : null }; } } }
Can anybody help?
Thanks,Mirek -
Tuesday, September 14, 2010 11:24 AM
I`ve got the same problem as MirekSk described. Can anyone help us ?
I think NullReferenceException is thrown by System.Activities.Core.Presentation.FlowchartDesigner.CleanupFlowchart() in some scenario strictly depending on implementation of this internal method and WorkflowDesigner configuration. Knowing some details of implementation I`m be able to figure out what is wrong in my WorkflowDesigner configuration.
Is that method thread safe moreover ?
Thanks in advanced !
-
Monday, September 20, 2010 5:18 AM
I'm in the same boat...
I noticed that this only happens for me when the flowchart is selected so I can fix the error sometimes by simply selecting a different activity. However if there is nothing to select other than the flowchart I am a bit stuffed.
designerView.MakeRootDesigner(anotherActivityInTheWorkflow);
Jason Bolstad -
Monday, September 20, 2010 9:16 PM
Well, I have managed to work around it. It's yuk, but it does fix the issue. Basically everytime I reload the workflowDesigner, or close one I call a cleanup method. This basically makes sure that the flowchart isn't the last active activity.
Anyway, hope this helps others.
DesignerView designerView = this.WorkflowDesigner.Context.Services.GetService<DesignerView>();
Cheers
if (designerView != null)
{
if (modelService != null)
{
designerView.MakeRootDesigner(modelService.Root);
//designerView.MakeRootDesigner(null);
Flowchart flowchart = modelService.Root.GetCurrentValue() as Flowchart;
if (flowchart!=null)
{
LoadWorkflow(new Sequence());
}
}
}
// Clean up the old workflow, this prevents an error when the old designer had a flowchart in it.
if (modelService != null)
{
modelService.Root.Content.ClearValue();
}
// Clearing the new model service, pretty much cleaning everything we can here.
System.Activities.Presentation.Services.ModelService modelService2 =
(System.Activities.Presentation.Services.ModelService)this.WorkflowDesigner.Context.Services.GetService(typeof(System.Activities.Presentation.Services.ModelService));
if (modelService2 != null)
{
modelService2.Root.Content.ClearValue();
}
Jason Bolstad -
Monday, October 18, 2010 6:24 PM
Jason,
I'd love to get this fix to work, but frankly I can't follow your example. First of all, you are referencing objects that are outside the scope of your code (such as "modelService"). Secondly, it's not clear what the method "LoadWorkflow" does, or what object it is a member of. Thirdly, in my workflows the root object is typically "ActivityBuilder", and I have to go one level deeper to find the base Flowchart object. If you could clarify exactly how tis fits into the context of a re-hosted WorkflowDesigner implementaiton it would be very helpful (hopefully) to workaround the problem of this Null Reference exception occurring.
Ram
Ram -
Tuesday, October 19, 2010 10:02 PM
Hi Ram,
Like Jason said, try calling this before you reload the designer and/or after you close one.
/// <summary>
/// Clears the design surface.
/// </summary>
public void ClearDesignSurface()
{
if (WorkflowDesigner != null)
{
// Flowcharts can cause some issues.
CleanUpFlowChart();
// Clean up the old workflow, this prevents an error when the old designer had a flowchart in it.
if (_modelService != null)
{
_modelService.Root.Content.ClearValue();
}
// Clearing the new model service, pretty much cleaning everything we can here.
System.Activities.Presentation.Services.ModelService modelService2 =
(System.Activities.Presentation.Services.ModelService)this.WorkflowDesigner.Context.Services.GetService(typeof(System.Activities.Presentation.Services.ModelService));
if (modelService2 != null)
{
modelService2.Root.Content.ClearValue();
}
}
}/// <summary>
/// Cleans up a flowchart.
/// </summary>
private void CleanUpFlowChart()
{
if (WorkflowDesigner != null)
{
DesignerView designerView = this.WorkflowDesigner.Context.Services.GetService<DesignerView>();
if (designerView != null)
{
if (_modelService != null)
{
designerView.MakeRootDesigner(_modelService.Root);
Flowchart flowchart = _modelService.Root.GetCurrentValue() as Flowchart;
if (flowchart != null)
{
Sequence instance = new Sequence();
System.Activities.Presentation.WorkflowDesigner workflowDesigner = new System.Activities.Presentation.WorkflowDesigner();
workflowDesigner.Load(instance);
this.WorkflowDesigner = workflowDesigner;
// Here we are adding the workflow designer to the workflow designer document panel.
this.WorkflowDesignerDocumentPanel.Content = this.WorkflowDesigner.View;
}
}
}
}
}_modelService is just : this._modelService = this.WorkflowDesigner.Context.Services.GetService<ModelService>();
Workflow designer is : System.Activities.Presentation.WorkflowDesigner WorkflowDesignerThe WorkflowDesignerDocumentPanel is where the WorkflowDesigners view is added to the form. Hope this helps.
Greg- Proposed As Answer by Greg Randall NZ Tuesday, October 19, 2010 10:04 PM
-
Wednesday, October 20, 2010 10:40 AM
Hi Greg,
Why do we need to query modelService twice?
First in when we obtain
_modelService
The second one is when we
modelService2
What are the differences between modelService2 and _modelService?
Regards,
Arinto
-
Thursday, October 21, 2010 10:37 PM
You don't have too.
_modelService was the ModelService before we assigned a new WorkflowDesigner to the WorkflowDesigner property, and modelService2 is the new workflow designers ModelService.
In my application I do some additional steps in the WorkflowDesigner property, that requires additional cleanup. I should have taken it out of this example for clarity. I hope the concept is still clear though?
Greg -
Friday, October 22, 2010 8:41 AM
Yup, thanks Greg.
Since I'm using MVVM and data binding between the ContentControl and WFDesigner, what I did is to change the UIElement that binded into the ContentControl when I unload the UserControl (UserControl is the container for the ContentControl).
So the code will be like this:
In the user control:
<UserControl x:Class="Agilent.BBox.UIPrototype.Sequencerv2.View.TestSequenceEditorView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="600" Loaded="SequenceEditor_Loaded" Unloaded="SequenceEditor_Unloaded"> <Grid> <ContentControl Name="sequenceEditor" Height="Auto" Width="Auto" Content="{Binding WfDesignerView}"/> </Grid> </UserControl>
Inside the code behind for the user control
private void SequenceEditor_Loaded(object sender, RoutedEventArgs e) { //Console.WriteLine("***************************************************EditorView is loaded!"); _viewModel.SetupDesignerView(); } private void SequenceEditor_Unloaded(object sender, RoutedEventArgs e) { //Console.WriteLine("+++++++++++++++++++++++++++++++++++++++++++++++++++EditorView is unloaded!"); _viewModel.ResetDesignerView(); }
Inside SetupDesignerView and ResetDesignerView:
thanks all :)public void ResetDesignerView() { TextBlock tblock = new TextBlock(); tblock.Text = "There are no usable controls associated to current work area"; tblock.TextWrapping = TextWrapping.Wrap; _wfDesignerView = tblock; OnPropertyChanged("WfDesignerView"); } public void SetupDesignerView() { if (_designer != null) { if (_designer.View != null) { _wfDesignerView = _designer.View; } } OnPropertyChanged("WfDesignerView"); }
arinto- Edited by arinto Friday, October 22, 2010 8:42 AM wrong term for code behind file
-
Friday, March 16, 2012 10:23 AM
I had this problem too when I had this code snippet in a function in my designer form...
DesignerMetadata metadata = new DesignerMetadata(); metadata.Register();The problem was solved when I moved the code to the constructor...
-
Monday, September 03, 2012 1:47 PM
Issue solved by installing .NET 4.0.3
http://www.microsoft.com/en-us/download/details.aspx?id=29053
Regards,
Jaydeep- Edited by meetjaydeep3 Monday, September 10, 2012 7:49 AM

