I write my own checkbox control. This checkbox, I put inside listbox using MVVM pattern. This user control have its own class, view model and xaml view.
Here is a class:
public class MultiSelectListBox
{
public bool IsChecked { get; set; }
public string Text { get; set; }
}
ViewModel for UserControl:
public partial class VMMultiSelectListBox : ViewModelBase
{
private bool _isChecked;
private string _text;
public VMMultiSelectListBox()
{
}
public VMMultiSelectListBox(MultiSelectListBox.BusinnesModel.MultiSelectListBox item)
{
IsChecked = item.IsChecked;
Text = item.Text;
}
public bool IsChecked
{
get { return _isChecked; }
set { _isChecked = value; NotifyPropertyChanged("IsChecked"); }
}
public string Text
{
get { return _text; }
set { _text = value; NotifyPropertyChanged("Text"); }
}
}
And here is xaml:
<UserControl x:Class="MES.UserControls.MultiSelectListBox.UCMultiSelectListBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MES.UserControls.MultiSelectListBox">
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Content="{Binding Text, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</UserControl>
Now I want to bind this UserControl inside my ListBox, which is located in main form.
This is what I'm using in my form xaml.
<Expander x:Name="expanderProccesses" Header="Procesy" IsExpanded="{Binding IsExpanded}" Grid.Column="1" Grid.Row="0" VerticalAlignment="Top" Margin="5,6,-30,0">
<ListBox ScrollViewer.VerticalScrollBarVisibility="Disabled" ItemsSource="{Binding ProccessFilter}" SelectedItem="{Binding SelectedProcess, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<ucLb:UCMultiSelectListBox/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Expander>
Last thing is view model of this form.
public VMMultiSelectListBox SelectedProcess
{
get { return _selectedProccess; }
set {
_selectedProccess = value;
NotifyPropertyChanged("SelectedProcess");
NotifyPropertyChanged("ProccessFilter");
}
}
public ObservableCollection<VMMultiSelectListBox> ProccessFilter
{
get { return _proccesFilter; }
set { _proccesFilter = value; NotifyPropertyChanged("ProccessFilter");}
}
Something I'm doing wrong. In selectedProcces it always leap in getter, but not in setter, which I need. I don't exactly know why.
I thing what you are trying to do can be achieved in a more standard context, by binding IsSelected property in ItemContainerStyle and using a CheckBox in the ItemTemplate:
<ListBox ScrollViewer.VerticalScrollBarVisibility="Disabled" SelectionMode="Extended" ItemsSource="{Binding ProccessFilter}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding Text}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsChecked, Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Please note that you should set SelectionMode="Extended".
Hope it helps.
Related
EDITED:
I've created three ListBoxes:
1st ListBox: listBox, which shows a list of U.S. States
2nd ListBox: listBox_Mirror, which contains a CheckBox to show the selected items of "listBox"
3rd ListBox: (No Name), which is supposed to show the checked items of "listBox_Mirror"
1st ListBox -> 2nd ListBox works fine. However, 2nd ListBox -> 3rd ListBox doesn't work, as you can see in the picture below:
Procedure:
Select all four items in the 1st ListBox.
Check the first two items (California and Illioni) in the 2nd ListBox's CheckBox.
See if California and Illioni are shown in the 3rd ListBox.
(In my case, nothing is shown.)
Here are my codes:
StateList.cs
using System.Collections.ObjectModel;
namespace CheckedListBox
{
public class StateList
{
public ObservableCollection<string> Data { get; }
public StateList()
{
Data = new ObservableCollection<string>();
Data.Add("California");
Data.Add("Illinoi");
Data.Add("Michigan");
Data.Add("New York");
}
}
}
MainWindow.xaml
<Window x:Class="CheckedListBox.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:CheckedListBox"
mc:Ignorable="d"
Title="MainWindow" Height="500" Width="400">
<Grid>
<ListBox ItemsSource="{Binding Path=Data}" x:Name="listBox" Margin="100,50,100,300" SelectionMode="Multiple"/>
<ListBox ItemsSource="{Binding SelectedItems, ElementName=listBox}" x:Name="listBox_Mirror" Margin="100,200,100,150">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<CheckBox Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<ListBox ItemsSource="{Binding SelectedItems, ElementName=listBox_Mirror}" Margin="100,350,100,25"/>
</Grid>
MainWindow.xaml.cs
using System.Windows;
namespace CheckedListBox
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new StateList();
}
}
}
... I've changed the Binding property of the 3rd ListBox based on the IntelliSense's suggestion, but it doesn't work, too.
Please tell me how to fix this. Thank you.
Two things, there is no binding to the IsChecked and hence nothing ever is set. Also your data is just reference of strings; you should change it to a class with at least two properties, one a Boolean and the other the string you have now. Then bind appropriately.
Here is how to do it. I have a model which is defined in code behind but you can get the idea on its structure.
<Page ...
xmlns:model="clr-namespace:WPFStack.Model"/>
...
<Page.Resources>
<model:Orders x:Key="Orders">
<model:Order CustomerName="Alpha"
OrderId="997"
InProgress="True" />
<model:Order CustomerName="Beta"
OrderId="998"
InProgress="False" />
<model:Order CustomerName="Omega"
OrderId="999"
InProgress="True" />
<model:Order CustomerName="Zeta"
OrderId="1000"
InProgress="False" />
</model:Orders>
Now with my Listbox
<ListBox ItemsSource="{StaticResource Orders}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding CustomerName}"
IsChecked="{Binding InProgress, Mode=TwoWay}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Running it shows this:
Model
namespace WPFStack.Model
{
/// <summary>Class Orders which is a placeholder for Xaml example data.</summary>
public class Orders : List<Order> { }
public class Order
{
public string CustomerName { get; set; }
public int OrderId { get; set; }
public bool InProgress { get; set; }
}
}
Mirror
Ok, now I will name the controls lbOriginal and lbSelected to be accessible in the code behind. The new control lbSelected will mirror as such without directly connecting to the lbOriginal control or the data:
<ListBox x:Name="lbShowSelected">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding .}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Then I would subscribe to events such as Loaded, Checked and UnChecked on the original.
<ListBox x:Name="lbOriginal"
ItemsSource="{StaticResource Orders}"
Loaded="ProcessChange">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding CustomerName}"
IsChecked="{Binding InProgress, Mode=TwoWay}"
Checked="ProcessChange"
Unchecked="ProcessChange"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So then at each step ProcessChange method properly updates the mirror (selected as I call it):
private void ProcessChange(object sender, RoutedEventArgs e)
{
if (lbOriginal.ItemsSource is Orders asOrders)
{
lbShowSelected.ItemsSource = null; // Inform control of reset
lbShowSelected.ItemsSource = asOrders.Where(ord => ord.InProgress)
.Select(ord => ord.CustomerName)
.ToList();
}
}
Then it is in sync and mirroring
Im trying to bind an ObservableCollection of
public class ProgressInfo : BindableBase, IProgress<Tuple<string, int>>
{
public ProgressInfo()
{
Message = "start";
ProgressBarValue = 50;
}
private string _message;
public string Message
{
get { return _message; }
set { _message = value; OnPropertyChanged(() => Message); }
}
private int _progressBarValue;
public int ProgressBarValue
{
get { return _progressBarValue; }
set { _progressBarValue = value; OnPropertyChanged(() => ProgressBarValue); }
}
public void Report(Tuple<string, int> value)
{
this.Message = value.Item1;
this.ProgressBarValue = value.Item2;
}
}
to WPF Toolkit BusyIndicator with custom content
<xctk:BusyIndicator DisplayAfter="0" IsBusy="{Binding IsBusy, Mode=OneWay}" >
<xctk:BusyIndicator.BusyContentTemplate>
<DataTemplate>
<StackPanel Margin="4">
<TextBlock Text="{x:Static lang:Resources.TRWAIMPORT}" FontWeight="Bold" HorizontalAlignment="Center"/>
<ItemsControl ItemsSource="{Binding ProgressInfos, UpdateSourceTrigger=PropertyChanged}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="4">
<TextBlock Text="{Binding ProgressInfo.Message, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay }"/>
<ProgressBar Value="{Binding Path=ProgressInfo.ProgressBarValue, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Height="15"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</xctk:BusyIndicator.BusyContentTemplate>
<xctk:BusyIndicator.ProgressBarStyle>
<Style TargetType="ProgressBar">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</xctk:BusyIndicator.ProgressBarStyle>
Also I'm passing objects from the ObervableCollection to my Tasks so they change their properties through the Report method.
But for some reason the BusyIndicator is never updated with new values and the ObservableCollection seems to always be empty (ItemsControl doesn't produce any items)
What am I doing wrong ? This approach worked on any other control but the BusyIndicator seems it doesn't get it right
So I have a listbox and a tool bar in my WPF app. The tool bar just has regular controls, and the listbox has vertical expanders.
I need the listbox to have a different set of expanders depending on what button is clicked. Right now it looks like such:
<ListBox>
<local:Select_Analysis_Panel/>
</ListBox>
Where local:Select_Analysis_Panel is seperate user control file containing the expanders. What is the best way to go about dynamically updating the ListBox control's content upon a button click?
For the last couple hours I've been trying to use set DataTemplates for each expander set and bind the to the items control property with little avail with the code below. I'm just trying to get basic framework laid out before setting up a MVVM interface. Later on I was going to replace the ItemsSource="Network_anal" with you know ItemsSource="{Binding WhatExpanderViewModelProperty}" or something like that.
<ListBox Width="250" Margin="5,0,0,0">
<ListBox.Resources>
<DataTemplate DataType="Select_Analysis_Panel">
<local:Select_Analysis_Panel/>
</DataTemplate>
<DataTemplate x:Key="Network_anal" DataType="NetworkAnalysis">
<local:NetworkAnalysis/>
</DataTemplate>.Resources>
<ListBox.Template>
<ControlTemplate>
<Border Background="Red"/>
</ControlTemplate>
</ListBox.Template>
<ItemsControl ItemsSource="Network_anal"/>
</ListBox>
Am I taking the right approach to this at all?
Here's what I'm trying to do. Below when the "File" button is clicked the side bar displays these 2 expanders:
And when "Network Design" button these expanders are dipslayed:
Option 1:
Subclassing the sections:
each of these sections could be subclassed from a base section class and a specific DataTemplate could be used for each:
<Window x:Class="MiscSamples.MultiToolbar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MiscSamples"
Title="MultiToolbar" Height="300" Width="300">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
</Window.Resources>
<DockPanel>
<ListBox ItemsSource="{Binding Sections}"
SelectedItem="{Binding SelectedSection}"
DisplayMemberPath="Name"
DockPanel.Dock="Top">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}"/>
<Setter Property="MinWidth" Value="80"/>
<Setter Property="MinHeight" Value="40"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border BorderBrush="Black" BorderThickness="1">
<ToggleButton IsChecked="{Binding IsSelected, Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}">
<ContentPresenter ContentSource="Content"/>
</ToggleButton>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<ScrollViewer Width="300" DockPanel.Dock="Left">
<ContentPresenter Content="{Binding SelectedSection}">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type local:FileSection}">
<TextBlock Text="User Control For File Section"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:NetworkDesignSection}">
<TextBlock Text="User Control For Network Design"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:SelectAnalysisSection}">
<TextBlock Text="User Control For Select Analysis"/>
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
</ScrollViewer>
<Grid Background="Gray">
<TextBlock Text="Design Surface" TextAlignment="Center" VerticalAlignment="Center" FontWeight="Bold"/>
</Grid>
</DockPanel>
</Window>
Code Behind:
public partial class MultiToolbar : Window
{
public MultiToolbar()
{
InitializeComponent();
var vm = new MainViewModel();
vm.Sections.Add(new FileSection() {Name = "File"});
vm.Sections.Add(new NetworkDesignSection() { Name = "Network Design" });
vm.Sections.Add(new SelectAnalysisSection() { Name = "Select Analysis" });
DataContext = vm;
}
}
Main ViewModel:
public class MainViewModel: PropertyChangedBase
{
private ObservableCollection<Section> _sections;
public ObservableCollection<Section> Sections
{
get { return _sections ?? (_sections = new ObservableCollection<Section>()); }
}
private Section _selectedSection;
public Section SelectedSection
{
get { return _selectedSection; }
set
{
_selectedSection = value;
OnPropertyChanged("SelectedSection");
}
}
}
Sections:
public abstract class Section:PropertyChangedBase
{
public string Name { get; set; }
private bool _isEnabled = true;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
_isEnabled = value;
OnPropertyChanged("IsEnabled");
}
}
private bool _isVisible = true;
public bool IsVisible
{
get { return _isVisible; }
set
{
_isVisible = value;
OnPropertyChanged("IsVisible");
}
}
//Optionally
//public string ImageSource {get;set;}
//ImageSource = "/Resources/MySection.png";
}
public class FileSection: Section
{
///... Custom logic specific to this Section
}
public class NetworkDesignSection:Section
{
///... Custom logic specific to this Section
}
public class SelectAnalysisSection: Section
{
///... Custom logic specific to File Section
}
//...etc etc etc
Result:
Notice that I'm using ToggleButtons bound to the ListBoxItem.IsSelected property to simulate a TabControl-like behavior.
You can set the DataContext of the whole form and bind the ItemsSource of the listbox, or set ItemsSource of the listbox to some collection directly.
I am trying to add a SelectionChanged interaction trigger to a ListBox in WPF so i can route the event to a command, but for some reason it's not working.
Here is my code
<Border Background="Transparent">
<ListBox Name="MyListBox"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectedValue="A"
SelectedValuePath="Content">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding MyCommand}"
CommandParameter="{Binding ElementName=MyListBox,
Path=SelectedIndex}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>A</ListBoxItem>
<ListBoxItem>B</ListBoxItem>
</ListBox>
</Border>
I guess i am doing something wrong here.
Your code works fine. All you need is to provide a suitable view model, e.g.
Note: using MVVM Light
public class TestViewModel : ObservableObject
{
public TestViewModel()
{
this.MyCommand = new RelayCommand<int>(i => Debug.WriteLine(i));
}
public RelayCommand<int> MyCommand { get; private set; }
}
Your Xaml with hard coded view model
<Window.DataContext>
<my:TestViewModel/>
</Window.DataContext>
<Border Background="Transparent">
<ListBox Name="MyListBox"
... etc
You should just bind the SelectedIndex to a property in your DataContext, which leads to simplier code :
<Border Background="Transparent">
<ListBox Name="MyListBox"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectedValue="A" SelectedValuePath="Content"
SelectedIndex="{Binding MyIndexProperty}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem >A</ListBoxItem>
<ListBoxItem >B</ListBoxItem>
</ListBox>
</Border>
// This is a property on a GalaSoft MVVMLIght ViewModel
/// <summary>
/// ThemeInfo of the current active theme
/// </summary>
public String ActiveTheme
{
get
{
if (activeTheme == null)
{
activeTheme = Properties.Settings.Default.Default_App_Theme;
}
return activeTheme;
}
set
{
if (activeTheme == value)
{
return;
}
var oldValue = activeTheme;
activeTheme = value;
// Update bindings
RaisePropertyChanged(ActiveThemePropertyName, oldValue, value, true);
if (value != null)
{
if (this.SwitchThemeCommand.CanExecute(value))
this.SwitchThemeCommand.Execute(value);
}
}
}
Sorry for the vague description, I can't think of a better way to put it.
Let's say that my ViewModel has a property as follows:
public List<MyClass> SubSystems { get; set; }
and the SubSystems class:
public class SubSystem
{
public string Name { get; set; }
public bool IsSelected { get; set; }
}
In the view, I'd like to bind the SubSystems property to, what I think would be, a list of checkboxes where the IsChecked and Name properties of the CheckBox is bound to the their respective properties, IsChecked for IsSelected and Content for Name.
I know I can make a ListBox in the XAML, but I'm not sure how I'd go about doing this using binding and a collection..
Thanks for the help!
Edit -
Here's the XAML:
<GroupBox Header="Sub-Systems" Grid.Column="0" Grid.Row="0" Margin="5">
<Grid>
<Grid.Resources>
<DataTemplate x:Key="checkBox">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</Grid.Resources>
<ListBox ItemTemplate="{StaticResource checkBox}" ItemsSource="{Binding SubSystems}" />
</Grid>
</GroupBox>
Edit #2 -
Just to clarify, all of the examples populate the box, but none of the examples are breaking on the breakpoints in the setters.
I think that instead of a ListBox, you probably want an ItemsControl. ListBoxes assume that you want to select one of the SubSystem but really, you just want to arrange the items with data templates:
<ItemsControl ItemsSource="{Binding SubSystems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Checkbox IsChecked="{Binding IsSelected, Mode=TwoWay}" Content="{Binding Name}" />
</DataTemplate>
<ItemsControl.ItemTemplate>
</ItemsControl>
How about this:
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked={Binding IsSelected, Mode=TwoWay} /><TextBlock Text={Binding Name} />
</StackPanel>
</DataTemplate>
Do you mean something like this?
SubSystem class
public class SubSystem : INotifyPropertyChanged
{
private string mName;
private Boolean mIsSelected = false;
public SubSystem()
{
}
public SubSystem(string name, Boolean isSelected)
{
this.Name = name;
this.IsSelected = isSelected;
}
public string Name
{
get { return mName; }
set
{
if (mName != value)
{
mName = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
}
public Boolean IsSelected
{
get { return mIsSelected; }
set
{
if (mIsSelected != value)
{
mIsSelected = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
ViewModel
ObservableCollection<SubSystem> mSubSystems = new ObservableCollection<SubSystem>();
public ObservableCollection<SubSystem> SubSystems
{
get { return mSubSystems; }
set { mSubSystems = value; }
}
View
<ListBox x:Name="lstSubsystems" ItemsSource="{Binding SubSystems}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}">
<ContentPresenter Content="{Binding Name}" />
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Hope that helps,
Wts
Modify the ListBox.ItemTemplate to use a checkbox, and bind the CheckBox.IsChecked to SubSystem.IsSelected and CheckBox.Content to SubSystem.Name:
XAML:
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}" Content="{Binding Name}" Margin="5" Focusable="False" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
C#:
private void window1_Loaded(object sender, RoutedEventArgs e)
{
this.SubSystems = new List<SubSystem>();
this.SubSystems.Add(new SubSystem() { Name = "SubSystem 1", IsSelected = false });
this.SubSystems.Add(new SubSystem() { Name = "SubSystem 2", IsSelected = false });
this.SubSystems.Add(new SubSystem() { Name = "SubSystem 3", IsSelected = true });
this.SubSystems.Add(new SubSystem() { Name = "SubSystem 4", IsSelected = false });
this.SubSystems.Add(new SubSystem() { Name = "SubSystem 5", IsSelected = true });
this.DataContext = this.SubSystems;
}
And make sure you set Focusable="False" to the CheckBoxes or else your users will be able to tab into them.
EDIT:
Also from what you added you might be missing the ElementName property (if SubSystems is NOT the DataContext of your window, you need to specify where the SubSystems property is coming from with the ElementName binding property):
<ListBox ItemTemplate="{StaticResource checkBox}" ItemsSource="{Binding ElementName=window1, Path=SubSystems}" />