• Workaround for DeckWorkspace issue: The smartpart is not present in the workspace

    Published by on September 9th, 2008 4:00 pm under CAB, SCSF

    6 Comments

    There are several questions in the SCSF forums asking about this excepction: The smartpart is not present in the workspace, when using the DeckWorkspace.

    Symptom

    When you show several views in the same DeckWorkspace and then close the application or terminate the parent WorkItem, you get the following exception:

    Exception

    Cause

    Every time a Smartpart is closed in a DeckWorkspace it is removed from its Controls collection. Then the ActivateTopmost method is called to show the previously shown Smartpart. That method takes the first element in the Controls collection of the DeckWorkspace and activates it (this.Controls[0]).

    When the Shell is being closed (by closing the application), the DeckWorkspace is disposed and starts to dispose all of its child elements. Therefore, because the DeckWorkspace is being disposed, the Controls collection cannot be modified.

    Consequently, when the Smarparts in the DeckWorkspace begin to get closed, they cannot be removed from the Controls collection (because it is being disposed). The ActivateTopmost method then receives a Smartpart that is no longer present in the DeckWorkspace and tries to activate it. This causes the “The SmartPart is not present in workspace” exception.

    Workaround

    Modify the Deckworkspace source code (you will need to have the SCSF source code installed) to avoid activating the previous Smartpart when the workspace is being disposed.

    You can perform the following steps to get this done:

    1. Open the CompositeUI-CS.sln solution.
    2. Right-click in the DeckWorkspace.cs file located in the Workspaces folder in the CompositeUI.WinForms project and select the View Code option.
    3. Replace the OnClose method for the following one:
      protected virtual void OnClose(Control smartPart)
      {
          this.Controls.Remove(smartPart);
      
          smartPart.Disposed -= ControlDisposed;
      
          if (!Disposing)
          {
              ActivateTopmost();
          }
      }

    4. Build the solution.
    5. Copy the recompiled CAB assemblies to the Lib folder of your SCSF solution.
    Technorati Tags: ,

    • Richard Stuppi

      On an unrelated note: I have two distinct views sharing one DeckWorkspace. Tabbing through the child controls of the active view will eventually shift focus to the child controls on the inactive view and begin tabbing through those. Has anyone else noticed this behavior?

    • Noam Mazouz

      If your SCSF solution supports WPF extensions, you will also need to rebuild the CompositeUI-WPFExtensions solution and copy the resulting Microsoft.Practices.CompositeUI.WPF.dll assembly to the Lib folder of your SCSF solution.

      Have fun!

    • Efy

      I use to get this error in Presenter of infrastructure.
      After tring your solution I started to get the same Error in:
      ThrowIfSmartPartNotShownPreviously in th file:SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\ElementHostWorkspace.cs

      Any Ideas??

      Thanks in adv.

      and this is the stack trace:
      at Microsoft.Practices.CompositeUI.WPF.ElementHostWorkspace`2.ThrowIfSmartPartNotShownPreviously(TSmartPart smartPart) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\ElementHostWorkspace.cs:line 381
      at Microsoft.Practices.CompositeUI.WPF.ElementHostWorkspace`2.Activate(Object smartPart) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\ElementHostWorkspace.cs:line 161
      at Microsoft.Practices.CompositeUI.WPF.DeckWorkspace.Activate(Object smartPart) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\DeckWorkspace.cs:line 329
      at Microsoft.Practices.CompositeUI.WPF.DeckWorkspace.ActivateTopmost() in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\DeckWorkspace.cs:line 126
      at Microsoft.Practices.CompositeUI.WPF.DeckWorkspace.OnClose(Control smartPart) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\DeckWorkspace.cs:line 161
      at Microsoft.Practices.CompositeUI.WPF.DeckWorkspace.Microsoft.Practices.CompositeUI.SmartParts.IComposableWorkspace.OnClose(Control smartPart) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\DeckWorkspace.cs:line 233
      at Microsoft.Practices.CompositeUI.WPF.ElementHostWorkspaceComposer`2.OnClose(TSmartPart smartPart) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\ElementHostWorkspaceComposer.cs:line 130
      at Microsoft.Practices.CompositeUI.WPF.ElementHostWorkspace`2.CloseInternal(TSmartPart smartPart) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\ElementHostWorkspace.cs:line 526
      at Microsoft.Practices.CompositeUI.WPF.ElementHostWorkspace`2.Close(Object smartPart) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\ElementHostWorkspace.cs:line 346
      at Microsoft.Practices.CompositeUI.WPF.DeckWorkspace.Close(Object smartPart) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\DeckWorkspace.cs:line 320
      at Ness.Diyur.Infrastructure.Interface.Presenter`1.CloseView() in C:\Users\Public\!SVN\MOCH.Client\Source\Infrastructure\Infrastructure.Interface\Presenter.cs:line 61
      at Ness.Diyur.PersonalFileModule.AssistanceFileLayoutViewPresenter.OnCloseView() in C:\Users\Public\!SVN\MOCH.Client\Source\Modules\PersonalFile\PersonalFileModule\Layouts\AssistanceFileLayoutViewPresenter.cs:line 42
      at Ness.Diyur.Infrastructure.Interface.Presenter`1.Dispose(Boolean disposing) in C:\Users\Public\!SVN\MOCH.Client\Source\Infrastructure\Infrastructure.Interface\Presenter.cs:line 94
      at Ness.Diyur.Infrastructure.Interface.Presenter`1.Dispose() in C:\Users\Public\!SVN\MOCH.Client\Source\Infrastructure\Infrastructure.Interface\Presenter.cs:line 75
      at Ness.Diyur.PersonalFileModule.AssistanceFileLayoutView.Dispose(Boolean disposing) in C:\Users\Public\!SVN\MOCH.Client\Source\Modules\PersonalFile\PersonalFileModule\Layouts\AssistanceFileLayoutView.Designer.cs:line 36
      at System.ComponentModel.Component.Dispose()
      at System.Windows.Forms.Control.Dispose(Boolean disposing)
      at Microsoft.Practices.CompositeUI.WPF.DeckWorkspace.Dispose(Boolean disposing) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\DeckWorkspace.cs:line 99
      at System.ComponentModel.Component.Dispose()
      at System.Windows.Forms.Control.Dispose(Boolean disposing)
      at System.ComponentModel.Component.Dispose()
      at System.Windows.Forms.Control.Dispose(Boolean disposing)
      at System.Windows.Forms.ContainerControl.Dispose(Boolean disposing)
      at System.ComponentModel.Component.Dispose()
      at System.Windows.Forms.Control.Dispose(Boolean disposing)
      at System.ComponentModel.Component.Dispose()
      at System.Windows.Forms.Control.Dispose(Boolean disposing)
      at System.Windows.Forms.ContainerControl.Dispose(Boolean disposing)
      at System.ComponentModel.Component.Dispose()
      at System.Windows.Forms.Control.Dispose(Boolean disposing)
      at System.Windows.Forms.ContainerControl.Dispose(Boolean disposing)
      at Ness.Diyur.Infrastructure.Layout.DiyurShellLayoutView.Dispose(Boolean disposing) in C:\Users\Public\!SVN\MOCH.Client\Source\Infrastructure\Infrastructure.Layout\DiyurShellLayoutView.Designer.cs:line 20
      at System.ComponentModel.Component.Dispose()
      at System.Windows.Forms.Control.Dispose(Boolean disposing)
      at Microsoft.Practices.CompositeUI.WPF.DeckWorkspace.Dispose(Boolean disposing) in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB-WPFExtensions\Source\CompositeUI.WPF\Workspaces\DeckWorkspace.cs:line 99
      at System.ComponentModel.Component.Dispose()
      at System.Windows.Forms.Control.Dispose(Boolean disposing)
      at System.Windows.Forms.ContainerControl.Dispose(Boolean disposing)
      at System.Windows.Forms.Form.Dispose(Boolean disposing)
      at Ness.Diyur.Infrastructure.Shell.ShellForm.Dispose(Boolean disposing) in C:\Users\Public\!SVN\MOCH.Client\Source\Infrastructure\Shell\ShellForm.Designer.cs:line 33
      at System.ComponentModel.Component.Dispose()
      at System.Windows.Forms.Form.WmClose(Message& m)
      at System.Windows.Forms.Form.WndProc(Message& m)
      at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
      at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
      at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
      at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
      at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
      at System.Windows.Forms.Form.DefWndProc(Message& m)
      at System.Windows.Forms.Control.WndProc(Message& m)
      at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
      at System.Windows.Forms.ContainerControl.WndProc(Message& m)
      at System.Windows.Forms.Form.WmSysCommand(Message& m)
      at System.Windows.Forms.Form.WndProc(Message& m)
      at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
      at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
      at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
      at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
      at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
      at System.Windows.Forms.Form.DefWndProc(Message& m)
      at System.Windows.Forms.Control.WndProc(Message& m)
      at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
      at System.Windows.Forms.ContainerControl.WndProc(Message& m)
      at System.Windows.Forms.Form.WmNcButtonDown(Message& m)
      at System.Windows.Forms.Form.WndProc(Message& m)
      at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
      at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
      at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
      at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
      at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
      at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
      at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
      at System.Windows.Forms.Application.Run(Form mainForm)
      at Microsoft.Practices.CompositeUI.WinForms.FormShellApplication`2.Start() in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB\CS\Source\CompositeUI.WinForms\FormShellApplication.cs:line 31
      at Microsoft.Practices.CompositeUI.CabApplication`1.Run() in C:\Users\Public\!SVN\SCSF-Apr2008\Blocks\CAB\CS\Source\CompositeUI\CabApplication.cs:line 81
      at Ness.Diyur.Infrastructure.Shell.ShellApplication.RunInDebugMode() in C:\Users\Public\!SVN\MOCH.Client\Source\Infrastructure\Shell\ShellApplication.cs:line 56
      at Ness.Diyur.Infrastructure.Shell.ShellApplication.Main() in C:\Users\Public\!SVN\MOCH.Client\Source\Infrastructure\Shell\ShellApplication.cs:line 47
      at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
      at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
      at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
      at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
      at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
      at System.Threading.ThreadHelper.ThreadStart()

    • http://blogs.southworks.net/mconverti Mariano Converti

      Hello Efy:
      This post was made to solve that issue when using the WinForms version of the DeckWorkspace. If you are using CAB Extensions for WPF, try to apply the same fix for the DeckWorkspace class inside the CompositeUI.WPF project. I didn’t try this solution but I’m think it should work.
      Let me know if this works for you. Thanks.
      Mariano Converti.

    • b

      Thank you very much. This helped me a lot!
      B.

    • Efy

      Maybe somone knows how can it be that the form loads after I am clicking the Shell (X) to close it.
      In the disposing of my view, suddenly the OnLoad of the View is called, according to the call stack it’s beeing raised from “External Code” probebly the CAB infrastructure?? so strange! Any Ideas?

About

Mariano Converti Profile Picture
Mariano Converti

Map