Print Page | Close Window

Duplicate ViewId's

Printed From: IdeaBlade
Category: DevForce
Forum Name: DevForce Classic
Forum Discription: For .NET 2.0
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=486
Printed Date: 28-Mar-2025 at 9:36am


Topic: Duplicate ViewId's
Posted By: orcities
Subject: Duplicate ViewId's
Date Posted: 10-Oct-2007 at 8:20am
I have created a custom view that will be used on tabs. Same as the Layout Demo's ThreePanelView. When I have more then one tab with this view, using the same type of TabController, I get an error:
 
An object with this ID alread exists: mXSmartPartPlaceholder
 
I have duplicated this error with the LayouDemo example. 
 
I believe this error is created because the ID which contains the Guid is determined at the base TabController, ThreePanelViewTabController, and not at the used TabController, UserRolesTabViewController.
 
I am looking at ways to fix this. If anyone comes up with something please let me know.



Replies:
Posted By: orcities
Date Posted: 10-Oct-2007 at 8:32am
This error is occuring when the base ViewFactory.AddNew method is called in the CreateView() method of the BaseTabController (ThreePanelTabVewController).
 
In stepping through it I have found that the Guid does change. But for some reason it only uses the last one submitted.


Posted By: orcities
Date Posted: 10-Oct-2007 at 8:47am

I have verified that the Id that is being set changes. This is done by adding the Guid to the panel id (LeftViewId = readonly string for guid + "_Left"). 

ViewFactory.AddNew(Constants.ViewNames.ActionView, WorkItem, LeftViewId);
 
So I do not understand how it is getting only the mLeftSmartPartPlaceholder as the id and causing a duplicate.


Posted By: orcities
Date Posted: 10-Oct-2007 at 12:56pm
As a test I add another tab to the Cabana project that uses the MasterDetailTab.
 
I added SalesRepCustomers2TabViewController to the go along with the SalesRepCustomersTabViewController  tab on the SalesRep page and got the same error.
 
 


Posted By: Bill Jensen
Date Posted: 10-Oct-2007 at 4:46pm
Congratulations--you've found a genuine "undocumented feature" in CAB.  It took Ward and myself quite a while to figure it out.
 
It turns out that when a view is being built (a consequence of ViewFactory.AddNew<>(), the object builder traverses the view's control hierarchy and adds certain controls to the Items collection of the workitem.  These are:
 
SmartParts (doesn't happen often because we rarely add SmartParts statically to a view),
 
Workspaces,
 
and
 
SmartPartPlacehoders.
 
These are added to the workitem Items collection using a key value composed of
 
1.  The value of the control's Name property
 
and
 
2.  The name of the control's type.
 
If the control's Name property is null, a GUID is used instead.
 
When the first ThreePanelView is created, its SmartPartPlaceholders are added to the items collection using the names mLeftSmartPartPlaceholder, etc.  When the second ThreePanelView is created, it attempts to add the same three names and throws the exception.  This will happen any time we try to add two instances of a view that contains any of the above three control types.
 
So,  the workaround is to give the SmartPartPlaceholders unique (or null) names.  This can be done in ThreePanelView in the PresenterReady() method:

/// <summary>

/// Configure the view once the Presenter declares it is ready.

/// </summary>

protected override void PresenterReady(EventArgs e)

{

// Set the SmartPartPlaceholder names to null so they will be

// added to the workitem's Items collection with unique (GUID) names

mLeftSmartPartPlaceholder.Name = null;

mMiddleSmartPartPlaceholder.Name = null;

mRightSmartPartPlaceholder.Name = null;

// Assign the view ids to be displayed in the SmartPartPlaceholders

mLeftSmartPartPlaceholder.SmartPartName = ThreePanelViewContext.LeftViewId;

mMiddleSmartPartPlaceholder.SmartPartName = ThreePanelViewContext.MiddleViewId;

mRightSmartPartPlaceholder.SmartPartName = ThreePanelViewContext.RightViewId;

}

Alternatively, we could use:

mLeftSmartPartPlaceholder.Name = ThreePanelViewContext.LeftViewId+"SPH";

mMiddleSmartPartPlaceholder.Name = ThreePanelViewContext.MiddleViewId+"SPH";

mRightSmartPartPlaceholder.Name = ThreePanelViewContext.RightViewId+"SPH";

Note that we can't create unique names (within the workitem) until the instance of the view is created.  Also the designer won't allow setting of null control names.
 
This should get you back on the air.
 
Bill & Ward


Posted By: orcities
Date Posted: 11-Oct-2007 at 7:27am
Works great. Tx.



Print Page | Close Window