Lesson 02.07

Populate Items in ComboBox

Let me also show you how to populate items in the ComboBox control inside your WPF Form. Overall it's not complicated, so it will be agood excercise for you.

Lesson 02.07

Populate Items in ComboBox

Let me also show you how to populate items in the ComboBox control inside your WPF Form. Overall it's not complicated, so it will be agood excercise for you.

Summary

Populating ComboBox Items

I've actually forgotten to show you how to populate items in the ComboBox.

So in this lesson I will show you how to write Wall Types in the ComboBox so user can select something. And you will be able to follow the same steps to add any other elements as well.

Get ComboBox Control

So firstly, we need to get the <ComboBox> control in our code. We've already given it x:Name = "UI_combobox", so you already know how to get it and we don't need to make any changes to the previous XAML code.

So let's create a new method and write the logic

# Populate ComboBox with WallTypes
self.populate_combo_with_walltypes()
Get Elements for ComboBox

We will continue working inside of this new method, and first of all we need to get some elements.

In my example, I will get all WallTypes by using FilteredElementCollector.

def populate_combo_with_walltypes(self):
    wall_types = FilteredElementCollector(doc).OfClass(WallType).ToElements()
    dict_wall_types = {Element.Name.GetValue(typ): typ for typ in wall_types}
Add ComboBoxItems

Now, let's prepare our data and add it to the combobox. It will be quite similar to how we worked with <ListBox> because <ComboBox> is also a container-like control.

💡 Also before we start adding anything, it's good idea to make Items.Clear(), so we can get rid of any placeholders we used in XAML code.

Then we will do the following:

  • Itearete through WallTypes

  • Create <ComboBoxItem>

  • Set Content as WallType.Name

  • Set Tag as WallType itself

  • Optionally, we can also select first or last item.

  • And in the end, we need to add <ComboBoxItem> to <ComboBox>

Here is the code:

def populate_combo_with_walltypes(self):
    wall_types      = FilteredElementCollector(doc).OfClass(WallType).ToElements()
    dict_wall_types = {Element.Name.GetValue(typ) : typ for typ in wall_types}

    # Clear ComboBox
    self.UI_combobox.Items.Clear()

    # Populate New Items
    first = True
    for wall_typ_name, wall_typ in dict_wall_types.items():
        combobox_item         = ComboBoxItem()
        combobox_item.Content = wall_typ_name
        combobox_item.Tag     = wall_typ

        if first:
            combobox_item.IsSelected = True
            first = False

        # Add Item to ComboBox
        self.UI_combobox.Items.Add(combobox_item)
Set default value as None

Sometimes you might also want to provide an option to select 'None'.

This way we need to manually create such item in the code and we can do it like this:

    def populate_combo_with_walltypes(self):
        wall_types      = FilteredElementCollector(doc).OfClass(WallType).ToElements()
        dict_wall_types = {Element.Name.GetValue(typ) : typ for typ in wall_types}

        # Clear ComboBox
        self.UI_combobox.Items.Clear()

        # Populate New Items
        for wall_typ_name, wall_typ in dict_wall_types.items():
            combobox_item         = ComboBoxItem()
            combobox_item.Content = wall_typ_name
            combobox_item.Tag     = wall_typ

            # Add Item to ComboBox
            self.UI_combobox.Items.Add(combobox_item)

        # Add None Option
        combobox_item = ComboBoxItem()
        combobox_item.Content = "None"
        combobox_item.Tag     = None
        combobox_item.IsSelected = True
        self.UI_combobox.Items.Add(combobox_item)

💡Just make sure you expect to get None as a valid result from your <ComboBox> and adjust logic accordingly.

Accessing Selected ComboBox Items

Lastly, we need to get the selected item and it's very easy. Since there can only be 1 selected item, we can use SelectedItem property. And since we story WallType as a Tag property, we also can reference that to get the actual element.

@property
def combobox_item(self):
    return self.UI_combobox.SelectedItem.Tag

Avoiding Errors on Empty Selection

Also, keep in mind that if you will be trying to read Tag property when nothing is selected in <ComboBox>, you will get an error.

So you might need to make an if statement before you do that, if it's possible to select nothing in the <ComboBox>.

if UI.combobox_item:
    print(UI.combobox_item)
    print(Element.Name.GetValue(UI.combobox_item))

Final Thoughts

Alright, and by now you should have a really advanced WPF Form working in pyRevit. We've covered really a lot during this 2nd module:

  • How-to create XAML Form

  • How to connect XAML to pyRevit

  • Event Triggers in WPF

  • How to use xName attribute

  • How to read user input

  • How to modify WPF controls with python

  • How to populate ListBox/ComboBox

  • How to implement SearchBox with events

  • And various little tips and tricks in between.

I hope that you learnt a lot and you now have the skills to create very advanced forms with pyRevit.

But we are not done yet. I still have more lessons for you and in the next module we will focus on how to create reusable forms for pyRevit.

So, you will learn how to create your form once and then reuse them across all scripts.

I wish you Happy Coding and I will see you soon.

🙋‍♂️ See you in the next lesson.
- EF

🙋‍♂️ See you in the next lesson.
- EF

Discuss the lesson:

P.S. Sometimes this chat might experience connection issues.
Please be patient or join via Discord app so you can get the most out of this community and get access to even more chats.

Discuss the lesson:

P.S. Sometimes this chat might experience connection issues.
Please be patient or join via Discord app so you can get the most out of this community and get access to even more chats.