I have tried binding a CheckBox IsChecked to IsSelected of a ListBoxItem in xaml. This way I can populate a dynamic list with corresponding checkboxes and I receive a list of checked items using the form. So far so good. But, how do I precheck items in the list programmatically, preferable in PowerShell?
I have been testing with a XAML that looks like this:
<Window x:Class="WpfHandler.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfHandler"
mc:Ignorable="d"
Title="Testing" Height="300" Width="250">
<Window.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<CheckBox Margin="5,2" IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource TemplatedParent}}">
<ContentPresenter />
</CheckBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Border Padding="10">
<Grid Margin="0 10 0 10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Name="Testing" Orientation="Horizontal">
<ListBox Name="Box_Test" ItemsSource="{DynamicResource test}" Height="220" SelectionMode="Multiple"/>
</StackPanel>
</Grid>
</Border>
</Window>
...and a Powershell script that looks like this:
add-type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Drawing
$xamlFile = "testing.xaml"
[xml]$xaml = (Get-Content $xamlFile -Raw) -replace 'x:Name', 'Name'
$xaml.Window.RemoveAttribute('x:Class')
$xaml.Window.RemoveAttribute('mc:Ignorable')
$xaml.SelectNodes("//*") | ForEach-Object {
$_.RemoveAttribute('d:LayoutOverrides')
}
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
try {
$Script:Form = [Windows.Markup.XamlReader]::Load( $reader )
# Get Name variables from form and set scope to script
$xaml.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $Script:Form.FindName($_.Name) -Scope script }
}
catch {
Write-Host "Unable to load Windows.Markup.XamlReader";
exit
}
$testdata = Get-Content "testdata.txt"
$Script:Form.Resources.Add("test", $testdata)
$Script:Form.ShowDialog()
Here is an example to select the first two items by index:
$Script:Form.Add_Loaded({
foreach( $i in 0, 1 ) {
$Box_Test.ItemContainerGenerator.ContainerFromIndex( $i ).IsSelected = $true
}
})
$Script:Form.ShowDialog()
ItemContainerGenerator
is a property of the ItemsControl
base class of ListBox
.