none
NullReferenceException in ReHosted Designer on double-click

    Soru

  • 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

     

    30 Temmuz 2010 Cuma 15:52

Tüm Yanıtlar

  • can you paste me your repro code so I can investigate?
    30 Temmuz 2010 Cuma 17:17
  • 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 });
      }
     }
    
    
    }
    
    
    02 Ağustos 2010 Pazartesi 09:00
  • thanks for your repro steps/

    I will take a look today and return you the result tomorrow.

    02 Ağustos 2010 Pazartesi 18:00
  • I had a try on your code, but I can't repro.

    can you paste me your xaml content?

    03 Ağustos 2010 Salı 18:08
  • 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

    04 Ağustos 2010 Çarşamba 07:46
  • Has anyone got any further thoughts on this?
    • Yanıt Olarak Öneren MirekSk 08 Eylül 2010 Çarşamba 14:51
    06 Ağustos 2010 Cuma 08:17
  • 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 build
    OS 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
    08 Eylül 2010 Çarşamba 15:02
  • 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 !

    14 Eylül 2010 Salı 11:24
  • 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
    20 Eylül 2010 Pazartesi 05:18
  • 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>();
                    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();
                    }
    Cheers
    Jason Bolstad
    20 Eylül 2010 Pazartesi 21:16
  • 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
    18 Ekim 2010 Pazartesi 18:24
  • 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 WorkflowDesigner
    The WorkflowDesignerDocumentPanel is where the WorkflowDesigners view is added to the form. Hope this helps.

    Greg
    19 Ekim 2010 Salı 22:02
  • 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

    20 Ekim 2010 Çarşamba 10:40
  • 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
    21 Ekim 2010 Perşembe 22:37
  • 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:

     

      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");
      }
    
    thanks all :)

     


    arinto
    • Düzenleyen arinto 22 Ekim 2010 Cuma 08:42 wrong term for code behind file
    22 Ekim 2010 Cuma 08:41
  • 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...

    16 Mart 2012 Cuma 10:23
  • Issue solved by installing .NET 4.0.3

    http://www.microsoft.com/en-us/download/details.aspx?id=29053

      

    Regards,
    Jaydeep


    03 Eylül 2012 Pazartesi 13:47