locked
Related Items for Manual Activity form RRS feed

  • Question

  • Hi,

    It's my turn to ask a question. I recently wrote a blog post about adding a Related Items tab to Manual Activity form. Everything worked fine unless I noticed that if I opened a manual activity's form from a work item's form (i.e. SR's), all controls on the Related Items tab were disabled. If I open a manual activity from any manual activity's view, it works fine.

    I actually haven't spent much time for the investigation, but the issue seems to be related to DataContext. Any idea? 


    Cheers,
    Marat
    Site: www.scutils.com  Twitter: LinkedIn: Graveyard:

    Thursday, May 21, 2015 6:22 PM

Answers

  • I think I may know what the problem is. When an activity is opened from the ActivityTab control (which all the main work item forms use, SR, Incident, etc), the ActivityTab "Fetches and Merges" a separate type projection into the main form's data context.

    The type projection it uses happens to be: System.WorkItem.WorkItemActivities.Projection (id 4A66EE5A-5EBC-1C0E-362A-BA6BBDB8C7FE)

    That type projection does include some of the components that the RelatedItems tab can expose..however, if the component aliases do not match, the related items tab won't have any components to display.

    So, for example, I took a quick look at your code and it looks like you're using "RelatedWorkItems" as the related work items component alias. The type projection used by the ActivityTab has a "RelatedWorkItem" component alias.

    Try changing the component aliases that you use to match those component aliases that already exist in the System.WorkItem.WorkItemActivities.Projection.

    From a quick look at your code and the ActivityTab's type projection, give this a try first:
    RelatedWorkItems -> RelatedWorkItem
    RelatedWorkItemsSource -> RelatedWorkItemSource
    RelatedConfigItems -> RelatedConfigItem
    LinkedKnowledgeArticles -> RelatedKnowledge
    FileAttachments -> FileAttachment

    I can't guarantee this'll work as I haven't actually tried it myself..but I've had to deal with those ActivityTab type projection aliases in the past, and making sure they match always cleared things up for me.

    In your manual activity form type projection, use the same aliases (and the same component paths, if you can) that the System.WorkItem.WorkItemActivities.Projection uses. Modify your code where you instantiate the related item tab to use those new component aliases. The related items tab should then work for both the activity form and parent work item sub forms.

    Give it a whirl and let me know if it worked for you. If not, we'll start looking at some custom FetchAndMergeSubPrjoection approaches.

    Thursday, May 21, 2015 6:38 PM
  • I just tried it and it worked fine. Did you change the aliases in your type projection and in your MARelatedItems control data context changed event handler?

        public partial class MARelatedItems : UserControl
        {
            public RelatedItemsPane relatedItemsPane;
            EnterpriseManagementGroup emg;
    
    
            public MARelatedItems()
            {
                InitializeComponent();
                emg = FrameworkServices.GetService<IManagementGroupSession>().ManagementGroup;
            }
    
            private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
            {
                if (this.DataContext is IDataItem)
                {
                    this.relatedItemsPane = new RelatedItemsPane((IRelatedItemsConfiguration)new WorkItemRelatedItemsConfiguration("RelatedWorkItem", "RelatedWorkItemSource", "RelatedConfigItem", "RelatedKnowledge", "FileAttachment"));
                    this.Content = this.relatedItemsPane;
                }
            }
        }
    

    Note the italicized line..the component aliases in the workitemsrelateditemsconfiguration need to match the type projection component aliases.

            <TypeProjection ID="ManualActivityCustomFormWithRelatedItems_TypeProjection" Accessibility="Public" Type="Activity!System.WorkItem.Activity.ManualActivity">
              <Component Path="$Context/Path[Relationship='Activity!System.WorkItemContainsActivity' SeedRole='Target']$" Alias="ParentWorkItem" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemCreatedByUser']$" Alias="ActivityCreatedBy" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="ActivityAssignedTo" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAboutConfigItem']$" Alias="ActivityAboutConfigItem" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemRelatesToWorkItem']$" Alias="RelatedWorkItem">
                <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAffectedUser']$" Alias="WorkItemAffectedUser" />
                <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="WorkItemAssignedTo" />
              </Component>
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemRelatesToWorkItem' SeedRole='Target']$" Alias="RelatedWorkItemSource">
                <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAffectedUser']$" Alias="SourceAffectedUser" />
                <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="SourceAssignedToUser" />
              </Component>
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemRelatesToConfigItem']$" Alias="RelatedConfigItem" />
              <Component Path="$Context/Path[Relationship='Knowledge!System.EntityLinksToKnowledgeDocument']$" Alias="RelatedKnowledge" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemHasFileAttachment']$" Alias="FileAttachment">
                <Component Path="$Context/Path[Relationship='SupportingItem!System.FileAttachmentAddedByUser']$" Alias="FileAttachmentAddedBy" />
              </Component>
            </TypeProjection>

    Here's the updated type projection..note the aliases match the aliases from the System.WorkItem.WorkItemActivities.Projection.

    I'm on SCSM 2012 R2, but I'm pretty sure this'll work on 2010 and up.

    • Edited by Aaron Croasmun Thursday, May 21, 2015 8:25 PM edit: included the code I used that works for me
    • Marked as answer by Marat Kuanyshev Friday, May 22, 2015 12:17 AM
    Thursday, May 21, 2015 8:19 PM

All replies

  • I think I may know what the problem is. When an activity is opened from the ActivityTab control (which all the main work item forms use, SR, Incident, etc), the ActivityTab "Fetches and Merges" a separate type projection into the main form's data context.

    The type projection it uses happens to be: System.WorkItem.WorkItemActivities.Projection (id 4A66EE5A-5EBC-1C0E-362A-BA6BBDB8C7FE)

    That type projection does include some of the components that the RelatedItems tab can expose..however, if the component aliases do not match, the related items tab won't have any components to display.

    So, for example, I took a quick look at your code and it looks like you're using "RelatedWorkItems" as the related work items component alias. The type projection used by the ActivityTab has a "RelatedWorkItem" component alias.

    Try changing the component aliases that you use to match those component aliases that already exist in the System.WorkItem.WorkItemActivities.Projection.

    From a quick look at your code and the ActivityTab's type projection, give this a try first:
    RelatedWorkItems -> RelatedWorkItem
    RelatedWorkItemsSource -> RelatedWorkItemSource
    RelatedConfigItems -> RelatedConfigItem
    LinkedKnowledgeArticles -> RelatedKnowledge
    FileAttachments -> FileAttachment

    I can't guarantee this'll work as I haven't actually tried it myself..but I've had to deal with those ActivityTab type projection aliases in the past, and making sure they match always cleared things up for me.

    In your manual activity form type projection, use the same aliases (and the same component paths, if you can) that the System.WorkItem.WorkItemActivities.Projection uses. Modify your code where you instantiate the related item tab to use those new component aliases. The related items tab should then work for both the activity form and parent work item sub forms.

    Give it a whirl and let me know if it worked for you. If not, we'll start looking at some custom FetchAndMergeSubPrjoection approaches.

    Thursday, May 21, 2015 6:38 PM
  • Probably related to the SR form's projection not including those relationships. maybe cheat with FetchAndMergeSubProjection()? see also https://social.technet.microsoft.com/Forums/en-US/a4af3df1-3427-40e0-a6ac-d3c66a01b5c5/viewing-custom-relationships-in-activities-from-the-parent-work-item?forum=customization

    edit: beat to the punch, with a better answer even.

    Thursday, May 21, 2015 6:59 PM
  • Hi Aaron and Thomas,

    Unfortunately the changing of the aliases didn't help. Even the pure MA's form now doesn't show related items.

    Thomas proposed to create a custom type projection for the SR form, but in this case I'll need to create TPs for other WI types and container activities as well to make the solution universal. It seems to be too complicated. The trick has to be simple and elegant.

    I guess that the issue is related to the datacontent's binding. It's curious how activities are opened from the Activity tab of the WI form. Why does it work from the MA's view and doesn't work from the WI form?


    Cheers,
    Marat
    Site: www.scutils.com  Twitter: LinkedIn: Graveyard:

    Thursday, May 21, 2015 7:34 PM
  • I just tried it and it worked fine. Did you change the aliases in your type projection and in your MARelatedItems control data context changed event handler?

        public partial class MARelatedItems : UserControl
        {
            public RelatedItemsPane relatedItemsPane;
            EnterpriseManagementGroup emg;
    
    
            public MARelatedItems()
            {
                InitializeComponent();
                emg = FrameworkServices.GetService<IManagementGroupSession>().ManagementGroup;
            }
    
            private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
            {
                if (this.DataContext is IDataItem)
                {
                    this.relatedItemsPane = new RelatedItemsPane((IRelatedItemsConfiguration)new WorkItemRelatedItemsConfiguration("RelatedWorkItem", "RelatedWorkItemSource", "RelatedConfigItem", "RelatedKnowledge", "FileAttachment"));
                    this.Content = this.relatedItemsPane;
                }
            }
        }
    

    Note the italicized line..the component aliases in the workitemsrelateditemsconfiguration need to match the type projection component aliases.

            <TypeProjection ID="ManualActivityCustomFormWithRelatedItems_TypeProjection" Accessibility="Public" Type="Activity!System.WorkItem.Activity.ManualActivity">
              <Component Path="$Context/Path[Relationship='Activity!System.WorkItemContainsActivity' SeedRole='Target']$" Alias="ParentWorkItem" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemCreatedByUser']$" Alias="ActivityCreatedBy" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="ActivityAssignedTo" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAboutConfigItem']$" Alias="ActivityAboutConfigItem" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemRelatesToWorkItem']$" Alias="RelatedWorkItem">
                <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAffectedUser']$" Alias="WorkItemAffectedUser" />
                <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="WorkItemAssignedTo" />
              </Component>
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemRelatesToWorkItem' SeedRole='Target']$" Alias="RelatedWorkItemSource">
                <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAffectedUser']$" Alias="SourceAffectedUser" />
                <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemAssignedToUser']$" Alias="SourceAssignedToUser" />
              </Component>
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemRelatesToConfigItem']$" Alias="RelatedConfigItem" />
              <Component Path="$Context/Path[Relationship='Knowledge!System.EntityLinksToKnowledgeDocument']$" Alias="RelatedKnowledge" />
              <Component Path="$Context/Path[Relationship='WorkItem!System.WorkItemHasFileAttachment']$" Alias="FileAttachment">
                <Component Path="$Context/Path[Relationship='SupportingItem!System.FileAttachmentAddedByUser']$" Alias="FileAttachmentAddedBy" />
              </Component>
            </TypeProjection>

    Here's the updated type projection..note the aliases match the aliases from the System.WorkItem.WorkItemActivities.Projection.

    I'm on SCSM 2012 R2, but I'm pretty sure this'll work on 2010 and up.

    • Edited by Aaron Croasmun Thursday, May 21, 2015 8:25 PM edit: included the code I used that works for me
    • Marked as answer by Marat Kuanyshev Friday, May 22, 2015 12:17 AM
    Thursday, May 21, 2015 8:19 PM
  • Hi again,

    My fault, Aaron. Sometimes during night hours I miss obvious things. Where's my youth? You're right I forgot to change the aliases in the constructor. Now it works like a charm. Thanks a lot!


    Cheers,
    Marat
    Site: www.scutils.com  Twitter: LinkedIn: Graveyard:

    Friday, May 22, 2015 12:17 AM