Search code examples
c#dictionarycomboboxtuplespicklist

C# PickList values to ComboBox (AutoTask API, Multi-Key Dictionaries)


I am currently coding a few things for an AutoTask implementation using the AT web services API (https://webservices5.autotask.net/ATServices/1.5/atws.asmx). To do anything you basically need to query AT for all of the picklist values first. This is fairly straight forward, however I'm having some trouble figuring out how to separate all of the "SubIssueTypes" so they can easily be linked to their parent value "IssueType".

I have been putting each PickList into a Dictionary, and making that dictionary the source for ComboBoxes within the application. This works great, except I'm not sure what the best way to do SubIssueTypes. Each IssueType has multiple SubIssueTypes linked to it, however AT has placed all of the SubIssueTypes in the same PickList.

How can I place all of the SubIssueTypes into their own ComboBox that only shows the values who's "pValue.parentValue" matches the currently selected IssueType value?

public static Dictionary<string, Resource> ResourcesById = new Dictionary<string, Resource>();
public static Dictionary<string, Account> AccountsById = new Dictionary<string, Account>();
public static Dictionary<string, string> ResourcesIdByName = new Dictionary<string, string>();
public static Dictionary<string, string> AccountsIdByName = new Dictionary<string, string>();
public static Dictionary<string, string> AccountsNameById = new Dictionary<string, string>();

public static Dictionary<string, string> StatusIdByName = new Dictionary<string, string>();
public static Dictionary<string, string> StatusNameById = new Dictionary<string, string>();
public static Dictionary<string, string> IssueType = new Dictionary<string, string>();
public static Dictionary<string, string> SubIssueType = new Dictionary<string, string>();
public static Dictionary<string, Tuple<string, string>> SubIssueLabel = new Dictionary<string, Tuple<string, string>>();
public static Dictionary<Tuple<string, string>, string> SubIssueValue = new Dictionary<Tuple<string, string>, string>();
public static Dictionary<string, string> Priority = new Dictionary<string, string>();
public static Dictionary<string, string> Source = new Dictionary<string, string>();
public static Dictionary<string, string> ServiceLevelAgreement = new Dictionary<string, string>();
public static Dictionary<string, string> TicketType = new Dictionary<string, string>();
public static Dictionary<string, string> QueueNameById = new Dictionary<string, string>();
public static Dictionary<string, string> QueueIdByName = new Dictionary<string, string>();
public static Dictionary<string, string> AssignedResourceRole = new Dictionary<string, string>();
public static Dictionary<string, string> AssignedResource = new Dictionary<string, string>();
public static Dictionary<string, string> AllocationCode = new Dictionary<string, string>();
public static Dictionary<string, string> ResourcesNameById = new Dictionary<string, string>();

public static void Preload()
    {

        var client = new SoapClient().Admin();
        AutotaskIntegrations ati = new AutotaskIntegrations();






        Field[] fieldInfo = client.GetFieldInfo(ati, "Ticket");

        foreach (var item in fieldInfo)
        {
            if (item.IsPickList)
            {
                foreach (var pValue in item.PicklistValues)
                {

                    switch (item.Name)
                    {

                        case "Status":
                            StatusIdByName.Add(pValue.Label, pValue.Value);
                            StatusNameById.Add(pValue.Value, pValue.Label);
                            break;
                        case "IssueType":
                            IssueType.Add(pValue.Label, pValue.Value);
                            break;
                        case "SubIssueType":
                            SubIssueLabel.Add(pValue.Label, new Tuple<string, string>(pValue.parentValue, pValue.Value));
                            SubIssueValue.Add(new Tuple<string, string>(pValue.parentValue, pValue.Value), pValue.Label);
                            break;
                        case "Priority":
                            Priority.Add(pValue.Label, pValue.Value);
                            break;
                        case "Source":
                            Source.Add(pValue.Label, pValue.Value);
                            break;
                        case "ServiceLevelAgreementID":
                            ServiceLevelAgreement.Add(pValue.Label, pValue.Value);
                            break;
                        case "TicketType":
                            TicketType.Add(pValue.Label, pValue.Value);
                            break;
                        case "QueueID":
                            QueueNameById.Add(pValue.Value, pValue.Label);
                            QueueIdByName.Add(pValue.Label, pValue.Value);
                            break;
                        case "AllocationCodeID":
                            AllocationCode.Add(pValue.Label, pValue.Value);
                            break;
                        case "AssignedResourceID":
                            AssignedResource.Add(pValue.Label, pValue.Value);
                            break;
                        case "AssignedResourceRoleID":
                            AssignedResourceRole.Add(pValue.Label, pValue.Value);
                            break;
                    }
                }
            }
        }
    }

Now, with most of the PickList -> Dictionaries I am able to simply specify the source as the dictionary.

private void FillCombos()
    {
        AutoTaskData.Preload();
        AutoTaskData.ResourcesIdByName.Add("", "clear");
        ResourceBox.ItemsSource = AutoTaskData.ResourcesIdByName;
        AutoTaskData.QueueIdByName.Add("", "clear");
        QueueBox.ItemsSource = AutoTaskData.QueueIdByName;
        AutoTaskData.StatusIdByName.Add("", "clear");
        StatusBox.ItemsSource = AutoTaskData.StatusIdByName;
    }

XAML:

<ComboBox x:Name="QueueBox" SelectedValuePath="Value" DisplayMemberPath="Key" SelectionChanged="QueueBox_SelectionChanged"  />
<TextBlock Margin="5,10,10,0">Resource</TextBlock>
<ComboBox x:Name="ResourceBox" SelectedValuePath="Value" DisplayMemberPath="Key" SelectionChanged="ResourceBox_SelectionChanged"  />
<TextBlock Margin="5,10,10,0">Status</TextBlock>
<ComboBox x:Name="StatusBox" SelectedValuePath="Value" DisplayMemberPath="Key" />

This obviously doesn't work for the SubIssueType's though, as they are all in one dictionary and I only want values displayed if an IssueType is selected that matches their "pValue.ParentValue" variable (or in other words the first tuple of the dictionaries key or value). Perhaps tuples aren't the way to go, however I'm not sure what the best implementation would be for this.


Solution

  • Tom,

    We merge the IssueTypes and SubIssueTypes into a single set of values. Here's how we do it.

    Let's assume we have 2 IssueTypes:

    • Hardware (id=1)
    • Software (id=2)

    And 4 SubIssueTypes:

    • Repair (id=1, Parent=1 Hardware)
    • Upgrade (id=2, Parent=1 Hardware)
    • Bug (id=3, Parent=2 Software)
    • Enhancement (id=4, Parent=2 Software)

    For this set of options, we combine it into 1 set of options:

    • Hardware (id=-1)
    • Hardware / Repair (id=1)
    • Hardware / Upgrade (id=2)
    • Software (id=-2)
    • Software / Bug (id=3)
    • Software / Enhancement (id=4)

    Notice that the items in my list that represent an IssueType with no SubIssueType are negative numbers. The others are positive.

    When the user submits a value of -1, we know it's for IssueType id=1. When they submit a value of 3, we do a lookup for SubIssueType id=3 to find that its parent id=2.

    Not sure if this will help you in your project, but it's worked well for us.

    Hope this helps,

    Travis