I'm relatively fresh to WPF and discovering XAML.
I've got one ListBox Name="EmployeeTitles" in XAML (shown below). For the purpose of demonstrating the problem DataContext = employees which is ObservableCollection<Employee>.
<ListBox Name="EmployeeTitles"
ItemsSource="{Binding}"
SelectionMode="Extended">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ToggleButton IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}">
<!--StackPanel will have more items-->
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}"/>
</StackPanel>
</ToggleButton>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My "Code Behind" class snippet looks as follows:
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
OnPropertyChanged();
}
}
private bool _isSelected;
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
_isSelected = value;
OnPropertyChanged();
}
}
I would like to show the selected items in a different control. For example have a list that shows only selected items. Can I somehow mark in XAML that I only only want to display items with IsChecked="True"? I know I could have another ObservableCollection storing only selected items and updating it in "Code Behind" whenever property IsSelected changes, but that seems like an overhead and I suppose there should be a way to do it in XAML?
You can bind the other listbox with the selecteditems of the original listbox. Try the below code.
<Grid>
<StackPanel Orientation="Horizontal">
<ListBox x:Name="Emp" ItemsSource="{Binding EmpCollection}" SelectionMode="Extended">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ToggleButton IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}">
<!--StackPanel will have more items-->
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}"/>
</StackPanel>
</ToggleButton>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox x:Name="SelectedEmp" ItemsSource="{Binding ElementName=Emp,Path=SelectedItems}" DisplayMemberPath="Title"/>
</StackPanel>
</Grid>
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
}
class ViewModel
{
public ObservableCollection<Emp> EmpCollection { get; set; }
public ViewModel()
{
EmpCollection = new ObservableCollection<Emp>();
for (int i = 0; i < 10; i++)
{
EmpCollection.Add(new Emp() {Title = "Title"+i});
}
}
}
class Emp:INotifyPropertyChanged
{
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
OnPropertyChanged();
}
}
private bool _isSelected;
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
_isSelected = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Related
I have 2 listviews, one that is prepopulated with a list of values and an empty list that should populate based on what is selected/deselected in the first view. I can get the second view to populate when a value is selected but I'm not sure how to remove an item if it's been deselected in the first view. If I do deselect a record it adds a null value to the 2nd list. I'm thinking there is a way around this with if/else statements but I'm thinking there might be a more elegant way to accomplish this.
View Model
private ObservableCollection<string> _firstList;
public ObservableCollection<string> FirstList
{
get => _firstList;
set
{
if (_firstList!= value)
{
_firstList= value;
RaisePropertyChanged(nameof(FirstList));
}
}
}
private string _selectedRecord;
public string SelectedRecord
{
get => _selectedRecord;
set
{
if (_selectedRecord!= value)
{
_selectedRecord= value;
RaisePropertyChanged(nameof(SelectedRecord));
_secondList.Add(_selectedRecord);
}
}
}
private ObservableCollection<string> _secondList=
new ObservableCollection<string>();
public ObservableCollection<string> SecondList
{
get => _secondList;
set
{
if (_secondList!= value)
{
_secondList= value;
RaisePropertyChanged(nameof(SecondList));
}
}
}
XAML -
<ListView ItemsSource="{Binding FirstList}"
SelectedItem="{Binding SelectedRecord}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected,
RelativeSource={RelativeSource
AncestorType=ListViewItem}}"/>
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView ItemsSource="{Binding SecondList}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Replace the string with a custom type and handle your logic of adding and removing items in the view model:
public class ListItem : INotifyPropertyChanged
{
public ListItem(string value) =>
Value = value;
public string Value { get; }
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set { _isSelected = value; RaisePropertyChanged(nameof(IsSelected)); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
View Model:
public ViewModel()
{
InitializeComponent();
DataContext = this;
FirstList.CollectionChanged += (s, e) =>
{
if (e.NewItems != null)
foreach (var newItem in e.NewItems.OfType<INotifyPropertyChanged>())
newItem.PropertyChanged += OnItemIsSelectedChanged;
if (e.OldItems != null)
foreach (var oldIrem in e.OldItems.OfType<INotifyPropertyChanged>())
oldIrem.PropertyChanged -= OnItemIsSelectedChanged;
};
FirstList.Add(new ListItem("a"));
FirstList.Add(new ListItem("b"));
FirstList.Add(new ListItem("c"));
}
private void OnItemIsSelectedChanged(object sender, PropertyChangedEventArgs e)
{
ListItem listItem = (ListItem)sender;
if (listItem.IsSelected)
{
if (!SecondList.Contains(listItem))
SecondList.Add(listItem);
}
else
SecondList.Remove(listItem);
}
public ObservableCollection<ListItem> FirstList { get; } =
new ObservableCollection<ListItem>();
public ObservableCollection<ListItem> SecondList { get; }
= new ObservableCollection<ListItem>();
View:
<ListView ItemsSource="{Binding FirstList}" SelectedItem="{Binding SelectedRecord}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}"/>
<TextBlock Text="{Binding Value}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView ItemsSource="{Binding SecondList}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Value}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This is MVVM in a nutshell.
Hi I have my list view as follows:
![][1]
<RelativePanel >
<ListView x:Name="StudentListView"
IsItemClickEnabled="True"
Width="1000"
ItemClick="Student_ItemClick" >
<ListView.ItemTemplate>
<DataTemplate x:Name="ABC">
<StackPanel
x:Name="ListItemPanel"
Orientation="Horizontal"
MaxWidth="500">
<TextBlock x:Name ="uName" Text="{Binding Username}"
Margin="20,0,20,8"
FontSize="24"
FontStyle="Italic"
FontWeight="SemiBold"
Foreground="DarkBlue"
/>
<CheckBox Name="AttendCheckBox"
HorizontalAlignment="Left"
Checked="AttendCheckBox_Checked"
IsChecked="False"></CheckBox>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<TextBlock Name="queryName" FontSize="20"></TextBlock>
<Button Name="finishBtn" Content="Finish" RelativePanel.Below="StudentListView" ></Button>
</RelativePanel>
I am trying to access each data item and check if checkbox is checked or not when user clicks on finish button that is on same page as listview. And I am having tough time trying to figure it out. Any hint on it would be great. Thank you
I checked your code. You did not need to use Checked event of CheckBox. Instead, you could declare a bool type property in your custom class and bind IsChecked to it and set Mode=TwoWay, then, once your checkbox's IsChecked value is changed, the source also will be updated. After that, you could filter the source to get the 'IsChecked=True' items.
According to your code snippet, I made a code sample for you reference:
<RelativePanel>
<ListView x:Name="StudentListView"
IsItemClickEnabled="True"
Width="1000" Height="500">
<ListView.ItemTemplate>
<DataTemplate x:Name="ABC">
<StackPanel
x:Name="ListItemPanel"
Orientation="Horizontal"
MaxWidth="500">
<TextBlock x:Name ="uName" Text="{Binding Username}"
Margin="20,0,20,8"
FontSize="24"
FontStyle="Italic"
FontWeight="SemiBold"
Foreground="DarkBlue"/>
<CheckBox Name="AttendCheckBox" HorizontalAlignment="Left" IsChecked="{Binding IsSelected,Mode=TwoWay}"></CheckBox>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<TextBlock Name="queryName" FontSize="20"></TextBlock>
<Button Name="finishBtn" Content="Finish" RelativePanel.Below="StudentListView" Click="{x:Bind finishBtn_Click}"></Button>
</RelativePanel>
public sealed partial class MainPage : Page
{
public ObservableCollection<Test> tests { get; set; }
public MainPage()
{
this.InitializeComponent();
tests = new ObservableCollection<Test>();
for (int i=0;i<100;i++)
{
tests.Add(new Test() {Username="name "+i });
}
StudentListView.ItemsSource = tests;
}
private void finishBtn_Click(object sender, RoutedEventArgs e)
{
var selectedStudents = tests.Where(x => x.IsSelected == true).ToList();
}
}
public class Test : INotifyPropertyChanged
{
private string _Username;
public string Username
{
get { return _Username; }
set
{
if (_Username != value)
{
_Username = value;
RaisePropertyChanged("Username");
}
}
}
private bool _IsSelected;
public bool IsSelected
{
get { return _IsSelected; }
set
{
if (_IsSelected != value)
{
_IsSelected = value;
RaisePropertyChanged("IsSelected");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs(PropertyName));
}
}
}
I have a ListBox where items are filtered based on text entered in a textbox (and when enter is pressed):
<TextBox DockPanel.Dock="Top" Margin="0,0,0,20" Width="200" HorizontalAlignment="Left" Text="{Binding Path=FilterText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TextBox.InputBindings>
<KeyBinding Command="{Binding Path=FilterSearchCommand}" Key="Enter" />
</TextBox.InputBindings>
</TextBox>
<ListBox DockPanel.Dock="Bottom" Name="lbItems" ItemsSource="{Binding Path=MyList, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Width="{Binding ActualWidth, ElementName=lbItems}" Cursor="Hand" Margin="10,10,0,10" VerticalAlignment="Center" MouseLeftButtonUp="UIElement_OnMouseLeftButtonUp">
<TextBlock Text="{Binding Path=Title}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
When ENTER is pressed in the textbox, the following command is executed:
FilterSearchCommand = new RelayCommand(() => {
MyList = new ObservableCollection < MyObject > (MyList.Where(x => x.Title.IndexOf(FilterText, StringComparison.InvariantCultureIgnoreCase) >= 0).ToList());
});
public RelayCommand FilterSearchCommand {
get;
}
public string FilterText {
get;
set;
}
public ObservableCollection < MyObject > MyList {
get;
set;
}
Basically on entering the command, the ObservableCollection is successfully updated, however the items in the list box remain unchanged.
Any ideas?
You are going to have a bit of an issue here - Upon a search, you will overwrite your 'MyList' object. So, once you filter, you cannot un-filter. You should look into using a CollectionViewSource.
You need to implement INotifyPropertyChanged, and in the setter of MyList you will notify the UI that the property is changed. Here's an example:
class MyViewModel : INotifyPropertyChanged
{
private ObservableCollection<MyObject> _myList;
public ObservableCollection<MyObject> MyList
{
get { return _myList; }
set
{
_myList = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
I have the following requirements:
Window will show a ListView with multiple items.
User should be able to check (Checkbox) any item.
a) If one item, all items should be unchecked and disabled.
b) If checked item is unchecked, than all items should be enabled.
As of now, I have the following incomplete code.
MainWindow XAML:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="520.149" Width="732.463">
<Window.Resources>
<ResourceDictionary Source="MainWindowResource.xaml" />
</Window.Resources>
<Grid>
<ListView x:Name="myListBox" ItemTemplate="{StaticResource OfferingTemplate}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="3" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
</Window>
DataTemplete for ListView:
<DataTemplate x:Key="OfferingTemplate">
<StackPanel>
<Grid IsEnabled="{Binding IsEnabled}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8"></ColumnDefinition>
<ColumnDefinition Width="120"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<Rectangle Grid.Column="0" Grid.RowSpan="3" Fill="#F4CA16" />
<Label
Grid.Column="1"
Grid.Row="0"
Content="{Binding Title}"
FontSize="18" FontWeight="Bold"
Margin="0,0,0,0" />
<TextBlock
Grid.Column="1"
Grid.Row="1"
FontSize="10"
Text="{Binding Description}"
Foreground="Black"
TextWrapping="WrapWithOverflow"
Margin="5,0,0,0" />
<CheckBox
Grid.Column="1"
Grid.Row="2"
FontSize="14"
IsChecked="{Binding IsSelected}"
VerticalAlignment="Bottom"
Margin="5,0,0,0">
<TextBlock Text="Select" Margin="0,-2,0,0"/>
</CheckBox>
</Grid>
</StackPanel>
</DataTemplate>
Model:
class MyModel
{
public string Title { get; set; }
public string Description { get; set; }
public bool IsSelected { get; set; }
public bool IsEnabled { get; set; }
}
ViewModel:
class MyViewModel : INotifyPropertyChanged
{
private MyModel offering;
public MyViewModel()
{
offering = new MyModel();
}
public int ID { get; set; }
public string Title
{
get { return offering.Title; }
set
{
offering.Title = value;
RaisePropertyChanged("Title");
}
}
public string Description
{
get { return offering.Description; }
set
{
offering.Description = value;
RaisePropertyChanged("Description");
}
}
public bool IsSelected
{
get { return offering.IsSelected; }
set
{
offering.IsSelected = value;
RaisePropertyChanged("IsSelected");
}
}
public bool IsEnabled
{
get { return offering.IsEnabled; }
set
{
offering.IsEnabled = value;
RaisePropertyChanged("IsEnabled");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
This is an interesting question. Since the action you want applies to all items in the list, this logic should in list class level. Your MyViewModel class is fine. You need add some logic in your list class and XAML but thanks to Prism, it is quite easy.
The list class (not shown in your post) Contains:
public ObservableCollection<MyViewModel> MyItems { get; set; } //Binding to ItemsSource
private ICommand _selectCommand;
public ICommand SelectCommand
{
get { return _selectCommand ?? (_selectCommand = new DelegateCommand<MyViewModel>(DoSelect)); }
}
private void DoSelect(MyViewModel myViewModel)
{
foreach(var item in MyItems)
if (item != myViewModel)
{
item.IsSelected = false;
item.IsEnabled = false;
}
}
private ICommand _unselectCommand;
public ICommand UnselectCommand
{
get { return _unselectCommand ?? (_unselectCommand = new DelegateCommand<MyViewModel>(DoUnselect)); }
}
private void DoUnselect(MyViewModel myViewModel)
{
foreach (var item in MyItems)
if (item != myViewModel)
{
item.IsEnabled = true;
}
}
There are two commands, one for selecting and the other for unselecting. The magic is on XAML:
<ListView ItemsSource="{Binding Path=MyItems}" x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=IsSelected}" IsEnabled="{Binding Path=IsEnabled}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding ElementName=listView, Path=DataContext.SelectCommand}"
CommandParameter="{Binding}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding ElementName=listView, Path=DataContext.UnselectCommand}"
CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Using Prism's triggers, you can map CheckBox's Checked and Unchecked event to your list view model's commands and passing the item view model as parameter.
It is working perfectly but one thing is annoying, that setting item's IsSelected is separate. When you check a CheckBox, the item behind is set to true through DataBinding but all others are set through parent view model. If your post is all your requirement, you can remove IsChecked binding and put the logic of setting one IsSelected inside list view model, which looks clenaer and easier to write test code.
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}" />