UI Form: Sheet Parameter Toggle

One of students has asked how to create a custom UI form for controlling "Appears in Sheet List" parameter across all sheets. The best way to achieve this functionality is to create a custom WPF UI Form. And that's exactly what I will provide to you.

P.S.
The code might look big, but we just need to define a bunch of UI elements and provide correct values. Overall it's not that complicated once you go through it. Plus, you can ask Chat GPT to help you understand it and make additional changes.

Happy Coding!

Form Preview

The form will list all Sheets in the project and report their toggle state of "Appears in Sheet List" parameter. You also have an option to change the value by using the checkbox right away.


Code

This is a quick prototype it's not perfect, but it's a great base for you to copy and make your own changes.


📄script.py

#-*- coding: utf-8 -*-
__title__   = "Toggle SheetVisibility Menu"
__doc__     = """Version = 1.0
Date    = 13.02.2025
________________________________________________________________
Description:
Create a UI form to control the toggle state of ViewSheet parameter:  'Appears in Sheet List'.

It's quick and dirty prototype 🧙‍♂️. 
________________________________________________________________
Author: Erik Frits"""


# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩  ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#====================================================================================================
from Autodesk.Revit.DB import *
from pyrevit import forms   # By importing forms you also get references to WPF package! IT'S Very IMPORTANT !!!
import wpf, os, clr         # wpf can be imported only after pyrevit.forms!
from pyrevit.forms import select_views

# .NET Imports
clr.AddReference("System")
from System.Collections.Generic import List
from System.Windows import Application, Window, Visibility
from System.Windows.Controls import CheckBox, Button, TextBox, ListBoxItem, TextBlock
from System import Uri

# ╦  ╦╔═╗╦═╗╦╔═╗╔╗ ╦  ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║  ║╣ ╚═╗
#  ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
#====================================================================================================
PATH_SCRIPT = os.path.dirname(__file__)
doc     = __revit__.ActiveUIDocument.Document #type: Document
uidoc   = __revit__.ActiveUIDocument
app     = __revit__.Application

# Global Variables
# all_views  = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
# dict_views = {'[{}]_{}'.format(view.ViewType,view.Name) : view for view in all_views}


# ╔╦╗╔═╗╦╔╗╔  ╔═╗╔═╗╦═╗╔╦╗
# ║║║╠═╣║║║║  ╠╣ ║ ║╠╦╝║║║
# ╩ ╩╩ ╩╩╝╚╝  ╚  ╚═╝╩╚═╩ ╩ MAIN FORM
#====================================================================================================
# Inherit .NET Window for your UI Form Class
class WPF_SheetToggle(Window):
    def __init__(self):
        # Connect to .xaml File (in the same folder!)
        path_xaml_file = os.path.join(PATH_SCRIPT, 'ListBoxSearch.xaml')
        wpf.LoadComponent(self, path_xaml_file)

        # Populate Listbox with Views
        self.populate_listbox()

        # Show Form
        self.ShowDialog()


    # ╔╦╗╔═╗╔╦╗╦ ╦╔═╗╔╦╗╔═╗
    # ║║║║╣  ║ ╠═╣║ ║ ║║╚═╗
    # ╩ ╩╚═╝ ╩ ╩ ╩╚═╝═╩╝╚═╝ METHODS
    def populate_listbox(self):
        """Add Sheet items to your ListBox."""
        # Clear ListBox
        self.UI_listbox.Items.Clear()

        # Get Sheets
        all_sheets  = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets).WhereElementIsNotElementType().ToElements()
        dict_sheets = {'[{}]_{}'.format(sheet.SheetNumber, sheet.Name): sheet for sheet in all_sheets}

        # Add ViewNames as CheckBoxes to ListBox
        for sheet_name, sheet in dict_sheets.items():
            self.create_listbox_item(sheet_name, sheet)



    def create_listbox_item(self, sheet_name, sheet):
        """Create ListBoxItem for each sheet"""

        # Create TextBlock to avoid error with '_'
        textblock = TextBlock()
        textblock.Text = sheet_name

        # Create CheckBox And add textblock to it
        checkbox = CheckBox()
        checkbox.Content = textblock
        checkbox.Tag = sheet  # You save your sheet to CheckBox.Tag parameter to access in other places...
        checkbox.Click += self.UIe_toggle_visibility  # assign event handler

        # Set Current Toggle State
        current_toggle = sheet.get_Parameter(BuiltInParameter.SHEET_SCHEDULED).AsInteger()
        checkbox.IsChecked = bool(current_toggle)

        # Add Checkbox to ListBoxItem
        listbox_item = ListBoxItem()
        listbox_item.Content = checkbox

        # PS You have a hierarchy ListBoxItem -> CheckBox -> TextBlock (it's important later if you need to modify it)

        # Add ListBoxItem to ListBox
        self.UI_listbox.Items.Add(listbox_item)


    # ╔═╗╦═╗╔═╗╔═╗╔═╗╦═╗╔╦╗╦╔═╗╔═╗
    # ╠═╝╠╦╝║ ║╠═╝║╣ ╠╦╝ ║ ║║╣ ╚═╗
    # ╩  ╩╚═╚═╝╩  ╚═╝╩╚═ ╩ ╩╚═╝╚═╝

    @property
    def search(self):
        return self.UI_search.Text

    # ╔╗ ╦ ╦╔╦╗╔╦╗╔═╗╔╗╔  ╔═╗╦  ╦╔═╗╔╗╔╔╦╗╔═╗
    # ╠╩╗║ ║ ║  ║ ║ ║║║║  ║╣ ╚╗╔╝║╣ ║║║ ║ ╚═╗
    # ╚═╝╚═╝ ╩  ╩ ╚═╝╝╚╝  ╚═╝ ╚╝ ╚═╝╝╚╝ ╩ ╚═╝
    def UIe_btn_run(self, sender, e):
        print('Form Submitted!')
        self.Close()


    def UIe_search_text_changed(self, sender, e):
        search_text = self.search.lower()

        if search_text:
            search_words = search_text.split()

            for listbox_item in self.UI_listbox.Items:
                checkbox  = listbox_item.Content
                textblock = checkbox.Content
                view_name = textblock.Text.lower()

                if all(word in view_name for word in search_words):
                    listbox_item.Visibility = Visibility.Visible
                else:
                    listbox_item.Visibility = Visibility.Collapsed

        if not search_text:
            for listbox_item in self.UI_listbox.Items:
                listbox_item.Visibility = Visibility.Visible



    def UIe_toggle_visibility(self,sender, e):
        # Sender = CheckBox because that's where event is coming from
        sheet = sender.Tag

        #⚠️ It's best to create a single transaction for all changes.
        # I'm too lazy to make it properly right now
        with Transaction(doc,'Change Sheet Visibiltiy Parameter') as t:
            t.Start()

            p_visibility = sheet.get_Parameter(BuiltInParameter.SHEET_SCHEDULED)
            value = 1 if p_visibility.AsInteger() ==0 else 0
            p_visibility.Set(value) #set opposite value from current one

            t.Commit()



# Show form to the user
UI = WPF_SheetToggle()

📄ListBoxSearch.xaml

<Window Title="EF-First WPF Form"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="Auto" Width="300" MinHeight="150" 
        WindowStartupLocation="CenterScreen" ResizeMode="NoResize"
        SizeToContent="Height">

    <!--Stack Panel for all elements-->
    <StackPanel Margin="10" >

        <!--ListBox of Random Views-->
        <StackPanel Margin="5">
            <!--ListBox Label-->
            <TextBlock Text="Select Views:" FontWeight="Bold" Margin="0,0,0,5"/>

            <!--Search Box-->
            <DockPanel Margin="5">
                <TextBlock Text="🔎" Margin="0,0,5,0" />
                <TextBox x:Name="UI_search" TextChanged="UIe_search_text_changed"/>
            </DockPanel>

            <ListBox x:Name="UI_listbox" Height="300" >
                <!--ListBox Item with a CheckBox-->
                <ListBoxItem>
                    <DockPanel>
                        <CheckBox Content="View - A"/>
                    </DockPanel>
                 
                </ListBoxItem>

                <ListBoxItem>
                    <CheckBox Content="View - B" />
                </ListBoxItem>

                <ListBoxItem>
                    <CheckBox Content="View - C"/>
                </ListBoxItem>

            </ListBox>

        </StackPanel>

        <!--Separator-->
        <Separator Margin="5,5,5,12"/>

        <!--Submit Button-->
        <Button Content="Submit!" 
                Width="100" 
                Click="UIe_btn_run" />

⌨️ Happy Coding!
Erik Frits