Creating Dependent Drop Down Lists/Enum based on previous list

I am trying to create a generic paramaters “form” at the start of my test. These selected parameters will be used to build a JSON file for passing into my software package, and also ultimately for sending commands to the DUT as part of the Testing.

The challenge is that I have a hierarchical set of selections, for example:
1.) First Select Test Standard
2.) This will then limit the selection of DUT Types
3.) The DUT Type will then limit the selection of Modulation Formats
4.) The Modulation formats will then limit the selection of Data Rates.

I have tried this with Lists using Dictionary entries, and with enums. At least with enums, I can get the displayed lists to change based on the scenario above, and have no luck figuring out how to do that using lists.

With the enums, however, it is possible that the data rates could be the same for different DUT Types and modulation formats, thus my trying to use multiple conditions in the EnableIf statement, but that does not seem to be working. Here is an example of the Display code I used for one of the Data Rate choices:

[Display(“54”, “Shows the use of available values attribute.”, Order: 2.312, Group: “Data Rate”)]
[EnabledIf(“DutType2G”, DUTType2G.WLAN2_4GHz, “DutType5G”, DUTType5G.WLAN_5GHz_20MHz, HideIfDisabled = true)]
[EnabledIf(“Standard”, StandardVersion.EN_300_328, “Standard”, StandardVersion.EN_301_893, HideIfDisabled = true)]
[EnabledIf(“ModulationWiFi5G20”, ModulationWiFi5G20._11a20_Band1_2, “ModulationWiFi5G20”, ModulationWiFi5G20._11a20_Band3,
“ModulationWiFi5G20”, ModulationWiFi5G20._11a20_Band4, “ModulationWiFi2G”, ModulationWiFi2G._11g, HideIfDisabled = true)]
public bool DataRate54 { get; set; }

That does not seem to be working.

Does anyone have examples of how to enable hierarchical drop down lists?

Hi @ipa_test,

It sounds a bit like you should be using AvailableValuesAttribute. Did you check that out?

Works like this:


public int[] AvailableInts => {1,2,3}

// SelectedInt should show up as a drop down with 1,2,3 as available options.
[AvailableValues(nameof(AvailableInts))]
public int SelectedInt{get;set;}

I have tried that, but again, how do I select the second drop down list based on the selected value in the first list? And so on…

Ok, so if I understand you correctly, you want to derive the second list of available values based on the first selected.

The AvailableInts can do any kind of calculation available to the step. it can also calculate it based on other settings. See SelectedInt2 below.

public int[] AvailableInts => {1,2,3}

[AvailableValues(nameof(AvailableInts))]
public int SelectedInt{get;set;}

public int[] AvailableInts2 => new int[]{SelectedInt * 2,SelectedInt * 3,SelectedInt * 4};

// SelectedInts2 is based on the value of SelectedInt
[AvailableValues(nameof(AvailableInts2))]
public int SelectedInt2{get;set;}

So now, depending on what I choose first, the available selection for the second will change.

Well, that is kind of what I am trying to do, but it is a little more complicated than that, for example what i need to be able to do is:
if(SelectedInt == 1)
{
AvailableDUT = new string List (DUTTYPE1);
}
else
{
AvailableDUT = new stringList(DUTTYPE2);
}

I have yet to figure out how to do this…

So which part of this doesn’t work? I would probably do it in the getter of AvailableDUT and not in a setter, but I think it should work.

I can’t do an ‘If’ in the #region to set-up the form, I can’t figure out how to call a method to do the If statement… I am new to TAP and C#, so I am stumbling alot.

That’s fair. Don’t worry, we’ll get you through this :slight_smile:

C# as a language has evolved over time, so now there are more than one way of expressing the same thing. Which I think may be confusing you in this case.

This also applies to C# properties, which are used for settings.

So to clarify, this:

public int[] AvailableInts2 => new int[]{SelectedInt * 2,SelectedInt * 3,SelectedInt * 4};

Is 100% the same as this:

public int[] AvailableInts2 
{
   get
   {
       return new int[]{SelectedInt * 2,SelectedInt * 3,SelectedInt * 4};
   }
}

And it is inside that ‘getter’ I recommend you to add the if-code. For example:

```cs
public string[] AvailableInts2 
{
   get
   {
      if(SelectedInt == 1){
          return new string[]{"DUT1", "DUT3"};
      }
      return new string[]{"DUT2", "DUT3", "DUT4"};
    }
}

I am trying that now, but I get an error around:
if(SelectedInt == 1)

Says there is ambiguity between that SelectedInt and the other SelectedInt at the end of the first list…

And, BTW, thanks for your help. I have been wasting over 6 weeks time trying to figure this out…

Okay, I have figured out how to get the errors to clear, and this is the type of logic I want to implement, but still not sure if it is doing what I need it to do…

public Dut SelectedDut { get; set; }
[XmlIgnore]
//[Browsable(false)]
private List _listOfAvailableDUTTypes;
[Display(“Available Values”, “An editable list of values.”)]
public List ListOfAvailableDUTTypes
{
get
{
if (SelectedValue == “One”)
{
return new List{ “DUT1”, “DUT2”, “DUT3” };
}
else if(SelectedValue == “Two”)
{
return new List { “DUT27”, “DUT28”, “DUT30” };
}
else
{
return new List { “Scope”, “Signal Analzyer”, “VSG” };
}
}
set
{
_listOfAvailableValues = value;
OnPropertyChanged(“ListOfAvailableDUTTypes”);
}
}

OK, well, I am sorry it took that long. Did you find the examples included in the SDK package?

You write:

[Display(“Available Values”, “An editable list of values.”)]
public List ListOfAvailableDUTTypes

If you want it to be editable, this is not the right approach. Whenever the getter is called a new list is created (happens very often).

So do you want the user to edit the list or do you want it to be generated automatically?

I need the list to be generated automatically, and yes, I am using the example from the SDK… In fact, I would like to have the list pulled from the Dictionary set-up I have…

Ok, in that case you dont need the setter part:

 set{ /*...*/}

Otherwise I think it looks good. If you need to pull the values from a dictionary you can do:

get
{
   // Assuming the dictionary keys matches the type of the property.
    return myDictionary.Keys; 
}

So, nothing goes in the set branch?

1 Like

Holy crap, that looks like that might work… Thank you!

2 Likes

That’s great!

What I meant is, you can remove the ‘setter’ entirely. e.g:

// this is a get-only property (setter is removed):
string[] ListOfAvailableDutTypes
{
  get
  {
     return myDict.Keys;
  }
}