I'm trying to get an ItemsControl, which contains a grid, to display 9 checkboxes with different properties. However, only three ever show up.
I have a checkbox model class which has four properties representing the checkboxs' content, grid.row/column, and isChecked properties. I then create nine of these in my viewmodel and add them to an ObservableCollection
.
Next I bind the ItemsSource of my ItemsControl to the collection. Then, I add a checkbox control to the grid inside of the ItemsControl and bind the appropriate properties.
However, only the first three checkboxes are showing up and I have no idea why. I did verify via debugging that the collection being bound to does have the correct number of items.
Here's my CheckboxModel class:
public class CheckboxModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set { _isChecked = value; OnPropertyChanged("IsChecked"); }
}
private string _content;
public string Content
{
get { return _content; }
set { _content = value; OnPropertyChanged("Content"); }
}
private int _gridRow;
public int GridRow
{
get { return _gridRow; }
set { _gridRow = value; OnPropertyChanged("GridRow"); }
}
private int _gridColumn;
public int GridColumn
{
get { return _gridColumn; }
set { _gridColumn = value; OnPropertyChanged("GridColumn"); }
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
In my view model, I create a collection of these:
private ObservableCollection<CheckboxModel> _checkBoxList = new ObservableCollection<CheckboxModel>();
public ObservableCollection<CheckboxModel> CheckBoxList
{
get
{
return _checkBoxList;
}
set
{
if (null != value)
{
_checkBoxList = value;
OnPropertyChanged("CheckBoxList");
}
}
}
public void CreateCheckboxList()
{
CheckBoxList.Add(new CheckboxModel { IsChecked = true, Content = "Latitude", GridRow = 0, GridColumn = 0 });
CheckBoxList.Add(new CheckboxModel { IsChecked = true, Content = "Longitude", GridRow = 1, GridColumn = 0 });
CheckBoxList.Add(new CheckboxModel { IsChecked = true, Content = "Altitude", GridRow = 2, GridColumn = 0 });
CheckBoxList.Add(new CheckboxModel { IsChecked = true, Content = "Depth", GridRow = 0, GridColumn = 1 });
CheckBoxList.Add(new CheckboxModel { IsChecked = true, Content = "Speed", GridRow = 1, GridColumn = 1 });
CheckBoxList.Add(new CheckboxModel { IsChecked = true, Content = "Heading", GridRow = 2, GridColumn = 1 });
CheckBoxList.Add(new CheckboxModel { IsChecked = true, Content = "Roll", GridRow = 0, GridColumn = 2 });
CheckBoxList.Add(new CheckboxModel { IsChecked = true, Content = "Pitch", GridRow = 1, GridColumn = 2 });
CheckBoxList.Add(new CheckboxModel { IsChecked = true, Content = "VOS", GridRow = 2, GridColumn = 2 });
}
And then finally here's my xaml:
<ItemsControl ItemsSource="{Binding CheckBoxList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="149.6*" />
<ColumnDefinition Width="149.6*" />
<ColumnDefinition Width="149.6*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28*" />
<RowDefinition Height="28*" />
<RowDefinition Height="28*" />
</Grid.RowDefinitions>
<CheckBox Grid.Row="{Binding GridRow}"
Grid.Column="{Binding GridColumn}"
Margin="14,6,63,6"
VerticalAlignment="Center"
Content="{Binding Content}"
IsChecked="{Binding IsChecked}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Here's what it looks like:
Here's what I want it to look like:
The problem is that a new Grid is created for each item in your ObservableCollection
but you want a single Grid for all items.
You could set the ItemsPanel
of the ItemsControl
to your Grid
and use an ItemContainerStyle
to set the Grid.Row
and Grid.Column
attached properties of each item container.
This should work:
<ItemsControl ItemsSource="{Binding CheckBoxList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="149.6*" />
<ColumnDefinition Width="149.6*" />
<ColumnDefinition Width="149.6*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28*" />
<RowDefinition Height="28*" />
<RowDefinition Height="28*" />
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding GridRow}" />
<Setter Property="Grid.Column" Value="{Binding GridColumn}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Margin="14,6,63,6"
VerticalAlignment="Center"
Content="{Binding Content}"
IsChecked="{Binding IsChecked}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>