C# PickList 值到 ComboBox (AutoTask API, Multi-Key Dictionaries)

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

我目前正在为使用 AT Web 服务 API (https://webservices5.autotask.net/ATServices/1.5/atws.asmx) 的 AutoTask 实现编写一些代码。要执行任何操作,您基本上需要首先查询 AT 以获取所有选项列表值。这是相当简单的,但是我在弄清楚如何分离所有 "SubIssueTypes" 以便它们可以轻松地链接到它们的父值 "IssueType" 时遇到了一些麻烦。

我一直在将每个 PickList 放入字典中,并使该字典成为应用程序中组合框的来源。这很好用,除了我不确定做 SubIssueTypes 的最佳方法是什么。每个 IssueType 都有多个 SubIssueTypes 链接到它,但是 AT 已将所有 SubIssueTypes 放在同一个 PickList 中。

如何将所有 SubIssueType 放入它们自己的 ComboBox 中,该 ComboBox 仅显示 "pValue.parentValue" 与当前所选 IssueType 值匹配的值?

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;
                    }
                }
            }
        }
    }

现在,对于大多数 PickList -> 词典,我可以简单地将源指定为词典。

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" />

这显然不适用于 SubIssueType,因为它们都在一个字典中,我只希望在选择与它们的 "pValue.ParentValue" 变量(或换句话说第一个)匹配的 IssueType 时显示值字典键或值的元组)。也许元组不是要走的路,但是我不确定最好的实现是什么。

我相信我找到了一种方法来做到这一点。这是否是我不知道的最佳方式,但它似乎有效。

我在 "preload" 区域将字典更改为元组列表。

public static List<Tuple<string,string,string>> Subs = new List<Tuple<string, 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":

                            Subs.Add(new Tuple<string, string, string>(pValue.parentValue, pValue.Label, pValue.Value));
                            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;
                    }
                }
            }
        }
}

然后我创建了一个 CurrentSub 字典,用于保存当前选定 IssueType 的所有 SubIssueType。每次 IssueType 更改时都会清除字典。

private Dictionary<string, string> CurrentSub = new Dictionary<string, string>(); 

在 "ticket detail" 控件中,我使用以下内容填充组合框(最初和 IssueType 更改时)。

public partial class TicketDetailControl : UserControl
{

    private Ticket info = null;

    public TicketDetailControl()
    {
        InitializeComponent();
    }

    public Ticket Info
    {
        get { return info; }
        set
        {
            info = value;

            Description.Text = info.Description.ToString();

            Status.ItemsSource = AutoTaskData.StatusIdByName;
            Status.SelectedValue = info.Status.ToString();

            Queue.ItemsSource = AutoTaskData.QueueIdByName;
            Queue.SelectedValue = info.QueueID.ToString();

            IssueType.ItemsSource = AutoTaskData.IssueType;
            IssueType.SelectedValue = info.IssueType.ToString();

            CurrentSub.Clear();
            SubIssueType.ItemsSource = null;
            foreach (var item in AutoTaskData.Subs.Where(item => item.Item1 == (string)IssueType.SelectedValue))
            {
                CurrentSub.Add(item.Item2, item.Item3);
            }

            SubIssueType.ItemsSource = CurrentSub;
            SubIssueType.SelectedValue = info.SubIssueType.ToString();





        }

    }

    private Dictionary<string, string> CurrentSub = new Dictionary<string, string>(); 

    private void IssueType_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        CurrentSub.Clear();
        SubIssueType.ItemsSource = null;

        foreach (var item in AutoTaskData.Subs.Where(item => item.Item1 == (string) IssueType.SelectedValue))
        {
            CurrentSub.Add(item.Item2, item.Item3);
        }

        SubIssueType.ItemsSource = CurrentSub;


    }
}

汤姆,

我们将 IssueType 和 SubIssueType 合并为一组值。以下是我们的做法。

假设我们有 2 个问题类型:

  • 硬件(id=1)
  • 软件 (id=2)

和 4 个子问题类型:

  • 修复(id=1,Parent=1 硬件)
  • 升级(id=2,Parent=1 硬件)
  • 错误(id=3,Parent=2 软件)
  • 增强(id=4,Parent=2 软件)

对于这组选项,我们将其组合成一组选项:

  • 硬件(id=-1)
  • 硬件/维修 (id=1)
  • 硬件/升级 (id=2)
  • 软件(id=-2)
  • 软件/漏洞 (id=3)
  • 软件/增强 (id=4)

请注意,我的列表中表示没有 SubIssueType 的 IssueType 的项目是负数。其他都是阳性。

当用户提交值 -1 时,我们知道这是针对 IssueType id=1 的。当他们提交值 3 时,我们查找 SubIssueType id=3 以发现其 parent id=2.

不确定这是否对您的项目有帮助,但对我们来说效果很好。

希望对您有所帮助,

特拉维斯