Hello together,
today i want to show you some more examples for bindings.
Herefore i created a little window which shows the process names in different controls where you can stop the selected one of the combobox by pressing the “Stop”-button.
First we start with a simple binding by DisplayMemberPath for a combobox. This is pretty straightforward which could save you much time in the future.
XAML:
<ComboBox Name="cbbDienste" Grid.ColumnSpan="5" HorizontalAlignment="Left" Margin="10" VerticalAlignment="Top" Width="120" />
Code-Behind
$window.cbbDienste.DisplayMemberPath ='Name' $window.cbbDienste.ItemsSource = $prozesse $window.cbbDienste.SelectedIndex=0
The DisplayMemberpath must match a property of the element which you add in the ItemsSource. This way is very easy but will fit most of the use-cases.
The next example uses a listview with multiple values and can therefore be very useful.
XAML:
<ListView Name="lvVariables" Grid.Column="2" Grid.Row="0" Margin="15,70,15,15" Height="500"> <ListView.View> <GridView> <GridViewColumn Header="Name" Width="210" DisplayMemberBinding="{Binding Name}" /> <GridViewColumn Header="CPU" Width="250" DisplayMemberBinding="{Binding CPU}"/> </GridView> </ListView.View> </ListView>
Code-Behind:
$window.lvVariables.ItemsSource=$prozesse
You have to define the BindingNames in the XAML in this case. This names must match the propertynames of the element in the itemssource.
The last example is more granular. Here one of the bindings is integrated in the property of an element of the listview. As you see this is Font-Weight and could be nearly every other property of the elements.
XAML:
<ListView Grid.Column="4" Grid.Row="0" Name="lvEvents" Margin="15,70,25,15" > <ListView.View> <GridView> <GridView.Columns> <GridViewColumn> <GridViewColumnHeader Content="Name" Width="Auto" MinWidth="200px"/> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Path=Name}" TextAlignment="Left" Width="Auto" FontWeight="{Binding Path=Set}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView.Columns> </GridView> </ListView.View> </ListView>
Code-Behind:
[PSCustomObject]$paramList = @() Get-Process |Select-Object -First 20 | ForEach-Object { $paramList+= @([PSCustomObject]@{ Set = if($_.Name.Length -gt 8) { 'bold' } else { 'normal' } Name = $_.Name } ) }
To get this to work you will need an array of PSCustomObject elements. As you see the array is initiated and afterwards filled. A better readable construct follows:
[PSCustomObject]$paramList = @() foreach ($item in $prozesse | Select-Object -First 20) { if($item.Name.Length -gt 8) { $set='bold' } else { $set='normal' } $param=[PSCustomObject]@{ Set=$set Name = $item.Name } $paramList+=$param }
Changing the ItemsSource
By setting the itemssource again it is refreshed. But i will investigate how this can be done automatically.
$prozesse = Get-Process | Select-Object -First 6 $window.cbbDienste.ItemsSource = $prozesse
I hope you enjoyed it and will use some of these binding techniques. If you know how it is done it is pretty easy.
Greetings,
David
Full script:
function Convert-XAMLtoWindow { param ( [Parameter(Mandatory=$true)] [string] $XAML, [string[]] $NamedElements, [switch] $PassThru ) Add-Type -AssemblyName PresentationFramework $reader = [System.XML.XMLReader]::Create([System.IO.StringReader]$XAML) $result = [System.Windows.Markup.XAMLReader]::Load($reader) foreach($Name in $NamedElements) { $result | Add-Member NoteProperty -Name $Name -Value $result.FindName($Name) -Force } if ($PassThru) { $result } else { $result.ShowDialog() } } $xaml = @' <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="Fenster" SizeToContent="WidthAndHeight" ResizeMode="CanResizeWithGrip" Title="PowerShell WPF Window" Topmost="True"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Button Name="btnStop" Content="Stop" Grid.Column="4" HorizontalAlignment="Right" Margin="10" Grid.Row="4" VerticalAlignment="Bottom" Width="75"/> <ComboBox Name="cbbDienste" Grid.ColumnSpan="5" HorizontalAlignment="Left" Margin="10" VerticalAlignment="Top" Width="120" /> <ListView Name="lvVariables" Grid.Column="2" Grid.Row="0" Margin="15,70,15,15" Height="500"> <ListView.View> <GridView> <GridViewColumn Header="Name" Width="210" DisplayMemberBinding="{Binding Name}" /> <GridViewColumn Header="CPU" Width="250" DisplayMemberBinding="{Binding CPU}"/> </GridView> </ListView.View> </ListView> <ListView Grid.Column="4" Grid.Row="0" Name="lvEvents" Margin="15,70,25,15" > <ListView.View> <GridView> <GridView.Columns> <GridViewColumn> <GridViewColumnHeader Content="Name" Width="Auto" MinWidth="200px"/> <GridViewColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Path=Name}" TextAlignment="Left" Width="Auto" FontWeight="{Binding Path=Set}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView.Columns> </GridView> </ListView.View> </ListView> </Grid> </Window> '@ $window = Convert-XAMLtoWindow -XAML $xaml -NamedElements 'Fenster', 'btnStop', 'cbbDienste', 'lvVariables', 'lvEvents' -PassThru $window.cbbDienste.add_SourceUpdated( { [System.Object]$sender = $args[0] [System.Windows.RoutedEventArgs]$e = $args[1] #$window.cbbDienste.ItemsSource = $prozesse } ) $window.btnStop.add_Click( { [System.Object]$sender = $args[0] [System.Windows.RoutedEventArgs]$e = $args[1] $prozesse = Get-Process | Select-Object -First 6 $window.cbbDienste.ItemsSource = $prozesse Stop-Process -Name $window.cbbDienste.SelectedValue.Name } ) $prozesse = Get-Process | Select-Object -First 20 #Binding by Memberpath $window.cbbDienste.DisplayMemberPath ='Name' $window.cbbDienste.ItemsSource = $prozesse $window.cbbDienste.SelectedIndex=0 #Binding with setup bindinds in xaml file $window.lvVariables.ItemsSource=$prozesse #Binding with PSCustomObjects [PSCustomObject]$paramList = @() Get-Process |Select-Object -First 20 | ForEach-Object { $paramList+= @([PSCustomObject]@{ Set = if($_.Name.Length -gt 8) { 'bold' } else { 'normal' } Name = $_.Name } ) } # Same result - better readable ### [PSCustomObject]$paramList = @() ### foreach ($item in $prozesse | Select-Object -First 20) ### { ### if($item.Name.Length -gt 8) ### { ### $set='bold' ### } ### else ### { ### $set='normal' ### } ### $param=[PSCustomObject]@{ ### Set=$set ### Name = $item.Name ### } ### $paramList+=$param ### } $window.lvEvents.ItemsSource=$paramList $window.ShowDialog()