I'm not sure if this is the correct place to ask this, but here goes nothing:
I am creating a wpf window with code behind in Python. I can’t seem to figure out how to get the selected items of my comboboxes though (they are in a DataTemplate).
This is what I have so far, but I can’t seem to get the show_result function to work. Does anyone have any experience with this?
XML:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" MinHeight="450" Width="800" MinWidth="600">
<Window.Resources>
<DataTemplate x:Key="DataTemplate1" x:Name="DataTemplate1">
<Grid Height="auto" x:Name="GridTemplate">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<ComboBox ItemsSource="{Binding Area}" x:Name="Area1" Margin="3" Grid.Column="0" Grid.Row="1"/>
<ComboBox ItemsSource="{Binding Verdieping}" x:Name="Verdieping1" Margin="3" Grid.Column="1" Grid.Row="1"/>
<ComboBox ItemsSource="{Binding Gevel}" x:Name="Gevel1a" Margin="3" Grid.Column="2"/>
<ComboBox ItemsSource="{Binding Gevel}" x:Name="Gevel1b" Margin="3" Grid.Column="3"/>
<ComboBox ItemsSource="{Binding Gevel}" x:Name="Gevel1c" Margin="3" Grid.Column="4"/>
<ComboBox ItemsSource="{Binding Gevel}" x:Name="Gevel1d" Margin="3" Grid.Column="5"/>
</Grid>
</DataTemplate>
</Window.Resources>
<StackPanel Margin="10">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Label FontWeight ="Bold" Content="Title Block"/>
<ComboBox x:Name="TitleBlockComboBox" Margin="57,3,3,3" MinWidth="200" HorizontalAlignment="Left"/>
<Label FontWeight="Light" Content="> selecteer hier een horizontale A3-sheet" Margin="10,0,0,0" Foreground="#7F000000"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Label FontWeight ="Bold" Content="View Template"/>
<ComboBox x:Name="ViewTemplateComboBox" Margin="33,3,3,3" MinWidth="200" HorizontalAlignment="Left"/>
<Label FontWeight="Light" Content="> view template voor het verdieping plan" Margin="10,0,0,0" Foreground="#7F000000"/>
</StackPanel>
<Separator Height="5"/>
<Border Margin="0,10" Background="AliceBlue" CornerRadius="10">
<StackPanel x:Name="StackPanel1" Margin="5">
<Grid Height="auto" x:Name="Grid1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" FontWeight ="Bold" Content="Area"/>
<Label Grid.Column="1" Grid.Row="0" FontWeight ="Bold" Content="Verdieping plan"/>
<Label Grid.Column="2" Grid.Row="0" FontWeight ="Bold" Content="Gevel 1"/>
<Label Grid.Column="3" Grid.Row="0" FontWeight ="Bold" Content="Gevel 2"/>
<Label Grid.Column="4" Grid.Row="0" FontWeight ="Bold" Content="Gevel 3"/>
<Label Grid.Column="5" Grid.Row="0" FontWeight ="Bold" Content="Gevel 4"/>
</Grid>
</StackPanel>
</Border>
<StackPanel Orientation="Horizontal">
<Button x:Name="AddRowButton" Content="Add Row" Click="AddRow_Click" Margin="0,5,5,5" Width="200"/>
<Button x:Name="RemoveRowButton" Content="Remove Row" Click="RemoveRow_Click" Margin="5,5,0,5" Width="200"/>
</StackPanel>
<Button x:Name="show_result" Content="toon resultaat" Click="show_result" Margin="0,5"/>
</StackPanel>
</Window>
Python
### IMPORTS ###
from pyrevit import script
from pyrevit import forms
from System.Windows import *
from System.Windows.Controls import *
from rpw.ui.forms import Alert
### GLOBAL PARAMETERS (and temporary lists)###
xamlfile = script.get_bundle_file('ui.xaml')
countCombo = 0
countRows = 0
areasTemp = ["area1", "area2", "area3"]
verdTemp = ["verd0", "verd1", "verd2", "verd3", "verd4"]
gevelTemp = ["gevel1", "gevel2", "gevel3", "gevel4"]
titleBlocksDict = ["tb1", "tb2", "tb3", "tb4", "tb5", "tb6"]
viewTemplatesDict = ["vt1", "vt2", "vt3"]
### DEFINITIONS FOR THE ITEMSOURCES ###
class WPFItems:
def __init__(self, area, verdieping, gevel):
self.Area = area
self.Verdieping = verdieping
self.Gevel = gevel
GridTemplateData1 = WPFItems(areasTemp, verdTemp, gevelTemp)
### DEFINITIONS TO ADD/REMOVE ROWS ###
def add_row(window):
global countRows
countRows += 1
cc = ContentControl()
cc.Name = "contentControl{}".format(countRows)
cc.ContentTemplate = window.Resources["DataTemplate1"]
cc.Content = GridTemplateData1
window.StackPanel1.Children.Add(cc)
return cc
def remove_row(window):
global countRows
if countRows > 1:
countRows -= 1
num_children = len(window.StackPanel1.Children)
if num_children > 2:
last_child = window.StackPanel1.Children[num_children - 1]
window.StackPanel1.Children.Remove(last_child)
### CREATE THE WINDOW CLASS ###
class MyWindow(forms.WPFWindow):
def __init__(self):
forms.WPFWindow.__init__(self, xamlfile)
self.comboboxes = []
self.rows = []
row = add_row(self)
self.rows.append(row)
#default values
self.TitleBlockComboBox.ItemsSource = titleBlocksDict
self.ViewTemplateComboBox.ItemsSource = viewTemplatesDict
def AddRow_Click(self, sender, e):
row = add_row(self)
self.rows.append(row)
def RemoveRow_Click(self, sender, e):
remove_row(self)
if len(self.rows) > 1:
del self.rows[-1]
def show_result(self, sender, e):
result = []
for row in self.rows:
temp = row.ContentTemplate.FindName("Area1", row)
result.append(temp)
Alert(str(result), "geselecteerde waardes")
### SHOW WINDOW ###
if __name__ == '__main__':
my_window = MyWindow()
my_window.ShowDialog()
When I used only comboboxes, I could easily get the 'SelectedItem'. However, now that I'm using a ContentControl, I can't find the way to get that combobox within it.
Calling VisualTreeHelper.GetChild(row, 0)
should give you a reference to the ContentPresenter
which you can use to get a reference to the root Grid
in the template:
contentPresenter = VisualTreeHelper.GetChild(row, 0)
grid = VisualTreeHelper.GetChild(contentPresenter, 0)
You could then find the ComboBoxes
in the Children
collection of the Grid
, e.g.:
for child in grid.Children:
...