Error adding multiple views of the same type

Topics: CAB & Smart Client Software Factory
Jul 21, 2006 at 7:59 AM
originally posted by: samueljmueller

When calling this code more than once:

OrderView view = WorkItem.SmartParts.AddNew<OrderView>(Guid.NewGuid().ToString()); WorkItem.WorkspacesWorkspaceNames.ContentWorkspace.Show(view);

I get an error:

"An object with this ID already exists: orderView."

Apparently, even though I'm passing in a completely unique Guid for the id, the CAB wants to use the UserControl's name as a key when adding it to the workitem. I've tracked it down to this code:

private bool AddControlToWorkItem(WorkItem workItem, Control control)
{
if (ShouldAddControlToWorkItem(workItem, control))
{
if (control.Name.Length != 0)
workItem.Items.Add(control, control.Name);
else
workItem.Items.Add(control);

return true;
}

return false;
}

I've tried setting the Name property of the usercontrol to an empty string, and it seems to work. However, some of my views contain subviews, and i would have to clear those as well. Is there a reason why this code uses the control's name as a key for the hash, rather than the id that is originally provided? Is there a more elegant way to work around it?
Jul 21, 2006 at 12:17 PM
originally posted by: samueljmueller

I figured out the problem. Apparently, CAB will traverse through your view to find any child smart parts, and attempt to add those to the collection as well. In my case, I had an OrderView that also contained subviews, such as PaymentView, CustomerDetailsView. When I tried to add a second orderview with a unique id, the id would be used for the parent view, but any child views it found would be added via it's name. And since the first OrderView already contained an instance with the same name, it throws an exception.

My solution for now is to remove the SmartPart attribute from these child user controls, such as PaymentView and CustomerDetailsView. I'm not really sure if they need to be a smartpart anyway.
Oct 5, 2006 at 11:24 AM
originally posted by: BenMoran

I am just getting started on my first CAB/SCSF application and I am running into a couple of different issues all related to showing the same view multiple times and getting the error "An object with this ID already exists". These particular views are hosting in a DeckWorkspace and contain either a DeckWorkspace or a SmartPartPlaceholder that host another view. It is the "child" view that the error is referencing when I am adding a 2nd "parent" view as the other poster described.

It does not seem that removing the SmartPart attribute is working for me and I am wondering if someone can suggest another solution to this problem. Perhaps I am going about this all wrong. I believe a TabWorkspace will allow for the multiple views, but that does not really fit into my application visually.

Thanks in advance.
Oct 11, 2006 at 10:03 PM
originally posted by: CDSmith

Ben, I don't have your answer but I had the same problem and was stuck for a few hours. In my case, I had an Infragistics UltraTabWorkspace in a splitter panel on the child view and I changed it to an UltraTab control as a workaround. I'm interested in add'l comments on this issue also.

Regards
Oct 17, 2006 at 7:08 AM
originally posted by: samueljmueller

My current solution is to create a new WorkItemController for any view that may appear more than once. So in addition to your View and Presenter classes, create a Controller class as well. You would then instantiate a new controller for each new view that you want to show. My code looks like this:


ControlledWorkItem<AccountController> accountWorkItem = GetOrCreateAccountWorkItem(e.Data.Account);

private ControlledWorkItem<AccountController> GetOrCreateAccountWorkItem(Account account) {
ControlledWorkItem<AccountController> accountWorkItem = null;
if (WorkItem.WorkItems.Contains(account.Key)) {
accountWorkItem = WorkItem.WorkItems.Get<ControlledWorkItem<AccountController>>(account.Key);
} else {
accountWorkItem = WorkItem.WorkItems.AddNew<ControlledWorkItem<AccountController>>(account.Key);
accountWorkItem.Controller.Run(account);
}
return accountWorkItem;
}



This strategy works in a hierarchy as well, because within an accountview, there is a sub-workspace that regularly contains about 6 other views, and each of those subviews has a corresponding controller..