Duplicate IDs for Underlying SmartPart Controls

Topics: CAB & Smart Client Software Factory
Nov 4, 2005 at 11:39 AM
originally posted by: Tracie

I'm not sure if I am posting this to the right thread, but I have created a situation in my project that throws duplicate ID errors and I'm confused and concerned about the CAB architecture that creates it.

We have designed many small underlying financial planning controls that have been implemented as smart parts. These smart parts are primarily used as controls on more complex views or controls. For example, we may have two views that contain an instance of a smart part control called AssetCategoryControl. Both views named their underlying sub control assetCategory1 on the view. If we try to create both of these views inside the same work item to populate a split container, for example, CAB will throw an "Duplicate ID" exception because we have two underlying smart part controls with the same name.

To explain further, when I create the views in the workitem....

workItem.Items.Add<CashAccountView>()
workItem.Items.Add<SavingsAccountView>()

Then CAB will assign unique GUID ids for both views or I can assign unique identifiers as a parameter. But under the covers, CAB will loop thru all the underlying controls in each view and will also add them to the workitem if they are smartparts. But, for some reason, you use the "Name" property of the control as the ID. You cannot guarantee that every sub control name on a view will be unique across the scope of a project, especially when you have multiple programmers designing forms. I am very concerned about this and would like to know if I am misusing the CAB architecture or if this was an oversight in the design of assigning IDs. Why do you not create unique GUIDs when looping thru the underlying smart parts as well??????
Nov 4, 2005 at 12:25 PM
originally posted by: BradWilsonMSFT

They don't have to be unique across the whole project, just at the current WorkItem level.
Nov 5, 2005 at 3:11 AM
originally posted by: Tracie

Thanks Brad for the fast response!

You clarified that the name of each smart part on a control has to be named uniquely per workitem. Which prompts the question, to what level do we have to provide workitems. The one facet of a workitem that I was the most excited about was the ability to dynamically put together multiple smart parts on one form. With the current ID implementation, you are forcing us to make sure that everytime an underlying smart part is dropped on a view, it is named uniquely across the scope of a project. Yes, it has to be unique over the scope of the project, because we do not want to ever limit which views may be pieced together on a split container, tab form, etc.

For example, a user may select to create a financial transaction between a cash account to pay off an expense. If we have a workitem that drives this transaction which shows the cash account and expense controls in the same view, how can I guarantee that the developer that created both of these views used an unique name for any underlying smart part controls dropped on each of these controls. Are we using smart parts at a too gradual level?

Based on your response, we will need to implement a naming convention for dropping smart parts on higher level controls to prevent conflicting names if they are ever shared in one workitem. Why not use a Guid like you do for the top level smart parts when adding them to the work item if a specific name is not given??????
Nov 5, 2005 at 3:31 AM
originally posted by: BradWilsonMSFT

We use their names for two reasons: 1. Smart parts and smart part placeholders are hooked up together by name; 2. People will want to be able to find named smart parts by saying things like myWorkItem.SmartParts"Name".

We see WorkItems as the level of reusability in a system. They act like a use case controller. I do think it's reasonable to think that the authors all working together on a single use case in the system can come to some agreement to prevent name collisions. In many cases this won't be a significant issue, since you can so easily rename things.
Nov 5, 2005 at 4:27 AM
originally posted by: Tracie

We will create a naming convention for all smart parts when dropped on higher level controls.

However, I believe you may still have a bug in the cleanup code when removing a smart part from a work item. I have a tree workspace that I created that manages the navagation between 50 or more views. Since it is unreasonable to create 50 smartparts and hold their resources, I dynamically create each view within its associated workitem and remove it when another node is selected. Of course, like we have discussed, the AddNew<> for the workitem will add the smartpart to the workitem and all its underlying smart part controls as well using the "name" of each control. However, when I remove the smartpart from the workitem using myWorkItem.Items.Remove(sp); It only removes the key of the sp itself and does not cleanup the keys of the underlying controls. So, if they select the tree node of that view again, when I reinstantiate the view and add it to the workitem, it throws the duplicate ID again!!!
Nov 5, 2005 at 4:44 AM
originally posted by: BradWilsonMSFT

Hmm, I'll have to check on this. I think it should be cleaning up the child controls automatically when you remove the parent control.
Nov 5, 2005 at 6:11 AM
originally posted by: BradWilsonMSFT

I just double-checked the ControlSmartPartStrategy, and on remove of a control, it removes the hiearchy of controls recursively, so it should be working as you expected.

Can you provide a small repro?
Nov 5, 2005 at 6:23 AM
originally posted by: DLorenz

When a WorkItem gets terminated, the SmartPart's dispose gets called. However, it's dispose property is set to True, but the object as a whole still remains. You may have to do some tests like If (IsDisposed != true) ... do something.
Nov 5, 2005 at 7:09 AM
originally posted by: Tracie

Ok... I stepped thru the ControlSmartPartStrategy and it is not removing the nested controls because my top level control Site is null.

I am creating my tree workspace with a split container with a tree view to the left and smart parts being displayed in the Panel to the right. I dynamically create and dispose of the smart part views for the panel to the right as the user selects the tree node. When I add the smart part, even though the Site is null, you add all sub controls to the workitem. However, when I remove the smart part, you check the (site != null) before removing all nested items. So, you add them, but never remove them.

I'm a little confused of the smart part being sited. Do I have to create a smart part container or something different to view the smart parts in the right panel? I modeled my workspace after a sample from the hands-on-labs.
Nov 5, 2005 at 9:26 AM
originally posted by: BradWilsonMSFT

Okay, looking at the current version of the strategy in our source tree, I don't see anything regarding Site. So my guess is that the October CTP had a bug related to when we moved from ComponentModel to ObjectBuilder, which still referenced Site.

This will be fixed in the final release.
Nov 5, 2005 at 10:15 AM
originally posted by: Tracie

Thanks Brad!

When will the release be available????
Nov 5, 2005 at 11:58 AM
originally posted by: BradWilsonMSFT

Our schedule, as shown on the community home page, has a targetted final release date of November 9 (Wednesday).