Creating Select All Button

Hi everyone,
I’m making GUI with WPF in combination with Python.
I created a list of checkboxes. Now I want to create Select All and Deselect All buttons. Does anyone know how to do this?

Here’s the Python Code:

import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('IronPython.Wpf')

import wpf
from System import Windows

clr.AddReference("RevitServices")
import RevitServices 
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
from Autodesk.Revit.DB import*

from collections import OrderedDict

from pyrevit import UI
from pyrevit import forms
from pyrevit import script

xamlfile = script.get_bundle_file('ui.xaml')
doc = __revit__.ActiveUIDocument.Document

# Definitions
def SortedDictionary(keys, values):
    dictTemp = dict(zip(keys, values))
    keysSorted = sorted(keys)
    dictSorted = OrderedDict()
    for key in keysSorted:
        dictSorted[key] = dictTemp[key]
    return dictSorted

sheets = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets).WhereElementIsNotElementType().ToElements()

sheetNumbers = []
[sheetNumbers.append(sheet.get_Parameter(BuiltInParameter.SHEET_NUMBER).AsString()) for sheet in sheets]
sheetNames = []
[sheetNames.append(sheet.get_Parameter(BuiltInParameter.SHEET_NAME).AsString()) for sheet in sheets]
sheetsDict = SortedDictionary(sheetNumbers, sheets)

sheetNumbers.sort()
sheetNames.sort()

class CheckBoxListItem:
    def __init__(self, number, name, isChecked=False):
        self.Number = number
        self.Name = name
        self.IsChecked = isChecked

listViewData = []
for number, name in zip(sheetNumbers, sheetNames):
    item = CheckBoxListItem(number, name)
    listViewData.append(item)

class MyWindow(forms.WPFWindow):
    def __init__(self):
        forms.WPFWindow.__init__(self, xamlfile)
        self.ListBox1.ItemsSource = listViewData
    
    def SelectAll_Click(self, sender, e):
        #some code to select all
        return "wip"

    def DeselectAll_Click(self, sender, e):
        #some code to deselect all
        return "wip"

    @property
    def selected_sheets(self):
        selected_items = [item for item in self.ListBox1.Items if item.IsChecked]
        selected_numbers = [item.Number for item in selected_items]
        return [sheetsDict[name] for name in selected_numbers]
    
    @property
    def zoek_naar(self):
        return self.TextBox1.Text
    
    @property
    def vervang_door(self):
        return self.TextBox2.Text
    
    def button_click(self, sender, args):
        t = Transaction(doc, "change sheet nrs")
        t.Start()
        for sheet in my_window.selected_sheets:
            sheet.get_Parameter(BuiltInParameter.SHEET_NUMBER).Set(sheet.SheetNumber.Replace(my_window.zoek_naar, my_window.vervang_door))
        t.Commit()

    def button_click_close(self, sender, args):
        self.Close()

# Show dialogue
my_window = MyWindow()
my_window.ShowDialog()

And my WPF-code (XAML):

<Window xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:av="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="av"
        Title="Verander Sheet Number"
		MinWidth="550" Width="550" ResizeMode="NoResize"  SizeToContent="Height"  WindowStartupLocation="CenterScreen" >
    <Window.Resources>
        <DataTemplate x:Key="CheckBoxTemplate">
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding IsChecked}" />
                <TextBlock Text="{Binding Number}" Margin="10,0,0,0" FontWeight="Bold" />
                <TextBlock Text=" - " />
                <TextBlock Text="{Binding Name}" />
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <StackPanel Margin="10">
        <Label FontWeight ="Bold" Content="Selecteer Sheets"/>
        <Border BorderBrush="Black" BorderThickness="0.5">
        <ScrollViewer Height="200" Margin="5">
            <ItemsControl x:Name="ListBox1" ItemTemplate="{StaticResource CheckBoxTemplate}"/>
        </ScrollViewer>
        </Border>
        <StackPanel Orientation="Horizontal" Margin="0,5,0,0">
            <ToggleButton x:Name="SelectAllButton" Content="Select All" Click="SelectAll_Click" Width="100" Margin="0,0,10,0"/>
            <Button Content="Deselect All" Click="DeselectAll_Click" Width="100"/>
        </StackPanel>
        <Grid Margin="0,5,0,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120" />
                <ColumnDefinition Width="1*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="1*"/>
            </Grid.RowDefinitions>
            <Label FontWeight ="Bold" Content="Zoek naar" Grid.Column="0" Grid.Row="0"/>
            <TextBox Name="TextBox1" Text="ref" Margin="3" Width="150" MinWidth="150" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Left"/>
            <Label FontWeight ="Bold" Content="Vervang door" Grid.Column="0" Grid.Row="1"/>
            <TextBox Name="TextBox2" Text="woning" Margin="3" Width="150" MinWidth="150" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left"/>
        </Grid>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="3*" />
                <ColumnDefinition Width="1*" />
            </Grid.ColumnDefinitions>
            <Button Content="Verander Sheet Numbers" Click="button_click" Margin="0,5,5,0"/>
            <Button Content="Close" Click="button_click_close" Margin="0,5,5,0" Grid.Column="1"/>
        </Grid>
    </StackPanel>
</Window>

There’s a lot of information on C# on the internet, but I have 0 experience with that :confused:

Any help is welcome!

PS: If you see any weird or unlogical things in my code, feel free to let me know aswell.

This is how I would do it given your code:

    def SelectAll_Click(self, sender, e):
        newlist = []
        for item in self.ListBox1.Items:
            item.IsChecked = True
            newlist.append(item)
        self.ListBox1.ItemsSource = newlist
        return

    def DeselectAll_Click(self, sender, e):
        newlist = []
        for item in self.ListBox1.Items:
            item.IsChecked = False
            newlist.append(item)
        self.ListBox1.ItemsSource = newlist
        return
1 Like

Wow, I’m kind of embarrassed it was this simple. I’d been googling this for the past week haha.

Thank you so much!

However the solution described works for this situation I wouldn’t recommend doing it. You shouldn’t recreate the items source ever, you should update the items in it. For that you need a class for your items that implements INotifyPropertyChanged. Have a look at mvvm patterns

2 Likes