ThrowIfSmartPartNotShownPreviously hiding view

Topics: CAB & Smart Client Software Factory
Dec 16, 2006 at 5:27 AM
originally posted by: rgalante

I use a WindowWorkspace to load a modal view, and that view has a Cancel button that hides the view. I don't have a close method so I hide the view and remove it from the WorkItem.Items collection. I get an intermittent exception, which is generated by the Workspace.ThrowIfSmartPartNotShownPreviously method. I have wrapped an exception handler around the Workspace.Hide method call, but I'm wondering if I'm doing something wrong. Here is my code.

Show Modal View:

Dim oWinWS As WindowWorkspace = New WindowWorkspace()
Me.Workspaces.Add(oWinWS, "MyDialog")
Dim oWinSPI As WindowSmartPartInfo = New WindowSmartPartInfo()
oWinSPI.MaximizeBox = False
oWinSPI.MinimizeBox = False
oWinSPI.Modal = True
oWinSPI.StartPosition = FormStartPosition.CenterParent
oWinSPI.Title = "My Title"
Dim oView As MyView = Items.AddNew(Of MyView)()
oWinWS.Show(oView, oWinSPI)

On Cancel Click Event:

Dim oColl As ICollection(Of ExpirationView) = Me.Items.FindByType(Of MyView)
If oColl.Count > 0 Then
Dim oEnum As IEnumerator(Of MyView) = oColl.GetEnumerator()
Dim oView As MyView
If oEnum.MoveNext Then
oView = Enum.Current
If oView IsNot Nothing Then
' Wish I had a Close method!
Try
Me.Workspaces("MyDialog").Hide(oView) ' Exception sometimes occurs here
Catch ex As Exception
End Try
Me.Items.Remove(oView)
End If
End If
End If

Click the Cancel button once, and I get an exception (sometimes). Hit it again, and it works.
Dec 23, 2006 at 2:00 PM
originally posted by: JuanArg

Hi,
IWorkspace interface has a Close(smartpart) method. I think you miss that.

I found that using only the Close button is not a problem because your code removes the smartpart from the WorkItem.
But using the window close button (the X button) makes subsequent Workspace.Show() to fail with the known exception.
This is because when using the (X) button the smartpart is not removed.

You can implement a handler for the WindowWorkspace.SmartPartClosing event and removing the smartpart from the WorkItem in that handler.

I give you an example in C# using WorkspaceLocator and Close method.


//Attach to the event
oWinWS.SmartPartClosing += new EventHandler<WorkspaceCancelEventArgs>(oWinWS_SmartPartClosing);

//Event handler
void oWinWS_SmartPartClosing(object sender, WorkspaceCancelEventArgs e)
{
this.WorkItem.SmartParts.Remove(e.SmartPart);
}

//This is a CommandHandler for my CloseButton
CommandHandler(Constants.CommandNames.CloseHelloWorldCommand)
public void OnCloseHelloWorld(object sender, EventArgs e)
{
ICollection<IHelloWorldView> oViews = this.WorkItem.SmartParts.FindByType<IHelloWorldView>();
IEnumerator<IHelloWorldView> enumerator=oViews.GetEnumerator();
if (enumerator.MoveNext())
{
IWorkspaceLocatorService locator = this.WorkItem.Services.Get<IWorkspaceLocatorService>();
IWorkspace oWinWS = locator.FindContainingWorkspace(this.WorkItem, enumerator.Current);
oWinWS.Close(enumerator.Current);
}
}


Juan Arguello
http://staff.southworks.net/jarguello
Jan 1, 2007 at 2:46 AM
originally posted by: rgalante

Thanks for your response.

I missed the WindowWorkspace.Close method; I don't know how since it right where the Hide method is:-).

I changed my code to use your recommendations, and it works. I added the event handler for the SmartPartClosing event.

I put a breakpoint in the OnSmartPartClosing event, and I noticed that it fires once for every time the dialog is loaded. If I load the dialog once, the event fires once. If I load it again, the event fires twice. If I load it a third time, the event fires three times. That's three loads, but six events.

I had to remove the event handler after the WindowWorkspace closed to resolve this behavior. The local variable for the window workspace was not garbage-collected immediately after the function exited. And the events kept firing.
Jan 9, 2007 at 9:44 AM
originally posted by: JuanArg

Hi,
i'm happy my response could help you.
I was trying to reproduce the behavior you described and i think you are wiring the event to a method every time you show a view.
In my example code, i do something like this. Hope this can help you, if not give me more info about the events problem.


Example: (please note that the Workspace is added once to the Workspaces collection and the event is wired to the method only once too)

IWorkspace oWinWS;
if (this.WorkItem.Workspaces.Contains("MyDialog"))
{
oWinWS = this.WorkItem.Workspaces.Get("MyDialog");
}
else
{
oWinWS= this.WorkItem.Workspaces.AddNew<WindowWorkspace>("MyDialog");
oWinWS.SmartPartClosing += new EventHandler<WorkspaceCancelEventArgs>(oWinWS_SmartPartClosing);
}


Juan Arguello
http://staff.southworks.net/jarguello