Reputation: 1720
I have a number of checkboxes that represent columns that will be shown or hidden within a Datagrid. As of now they all work except for the Check All Checkbox. When selected it should as the name suggests check all of the checkboxes within the group.
None of these checkboxes are tied to a View Model, they only affect the appearance of the data on the View itself. One solution could be to implement all the checkboxes on the ViewModel and then take the Check All command and set all the flags to true. I'm just not fond of the idea because I'm adding 20 properties and various commands etc all JUST to support this one thing.
I had some ideas possibly using "IsThreeState" attribute but nothing cohesive. I'm not against rendering them in a different container either, I'm just not certain that it helps.
<Expander DockPanel.Dock="Top" Header="{x:Static p:Resources.shSettings}" IsExpanded="True">
<DockPanel>
<GroupBox Header="Filter Columns" DockPanel.Dock="Right">
<ag:AutoGrid Columns="150, 150, 150" RowCount="7" RowHeight="20">
<CheckBox Content="Check All" />
<CheckBox Content="Co. Name" x:Name="filterCoName" />
<CheckBox Content="Rating" x:Name="filterRating" />
<CheckBox Content="Severity (!)" x:Name="filterSeverity" />
<CheckBox Content="Stn ID" x:Name="filterStation" />
<CheckBox Content="MB" x:Name="filterMB" />
<CheckBox Content="New" x:Name="filterNew" />
<CheckBox Content="KV" x:Name="filterKV" />
<CheckBox Content="STE Rating" x:Name="filterSiteRating" />
<CheckBox Content="QCA" x:Name="filterQCA" />
<CheckBox Content="Area" x:Name="filterArea" />
<CheckBox x:Name="filterDuration" Content="Duration" />
<CheckBox Content="Plan in Place" x:Name="filterPIP" />
<CheckBox Content="Type" x:Name="filterType" />
<CheckBox Content="Rating(%)" x:Name="filterRatingPercent" />
<CheckBox Content="ID" x:Name="filterId" />
<CheckBox Content="Pre" x:Name="filterPre" />
<CheckBox Content="Deviation" x:Name="filterDeviation" />
<CheckBox Content="Status" x:Name="filterStatus" />
<CheckBox Content="Post" x:Name="filterPost" />
<CheckBox Content="Description" x:Name="filterDescription" />
</ag:AutoGrid>
</GroupBox>
</DockPanel>
</Expander>
Upvotes: 1
Views: 1661
Reputation: 7414
I know this was answered already, but I wanted to share a simple approach that you could use as well. You can create a SelectedItem view model and wrap a model in it. Then in your datacontext, you can fire an ICommand that iterates over a collection of SelectedItems and sets ISelected = true
.
/// <summary>
/// Provides a wrapper for objects that need to have their selected state checked.
/// </summary>
/// <typeparam name="T">The Type you are wrapping</typeparam>
public class SelectedItemViewModel<T> : ViewModel where T : class
{
/// <summary>
/// The item
/// </summary>
private readonly T item;
/// <summary>
/// The selected value of Item
/// </summary>
private bool isSelected;
/// <summary>
/// Initializes a new instance of the <see cref="SelectedItemViewModel{T}" /> class.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="eventService">The event service.</param>
/// <param name="initialSelectedState">if set to <c>true</c> [initial selected state].</param>
public SelectedItemViewModel(T item, bool initialSelectedState = false)
{
this.item = item;
this.isSelected = initialSelectedState;
this.eventService = eventService;
}
/// <summary>
/// Gets the item.
/// </summary>
public T Item
{
get
{
return this.item;
}
}
/// <summary>
/// Gets or sets a value indicating whether this instance is selected.
/// </summary>
public bool IsSelected
{
get
{
return this.isSelected;
}
set
{
this.isSelected = value;
this.OnPropertyChanged();
}
}
}
If you are just strictly wanting to display the content, and not have any real data, then in the view models constructor set it up like this.
private List<selectedItem<string>> data;
public MainViewModel()
{
this.data = new List<SelectedItem<string>>
{
new SelectedItem<string>("Co. Name");
new SelectedItem<string>("Rating");
// Etc.
}
}
public List<SelectedItem<string>> Data
{
get { return this.data; }
set { this.data = value; this.OnPropertyChanged(); }
}
Finally, in your XAML you just bind the data grid's ItemSource
property to your collection, and bind the checkbox's to the IsSelected property. This example uses a DataGrid, since I don't know what data grid you are using in the snippet you provided.
<DataGrid ItemsSource="{Binding Path=Data}"
DockPanel.Dock="Top"
AutoGenerateColumns="False"
HorizontalContentAlignment="Center"
HorizontalAlignment="Stretch"
MouseDoubleClick="DataGrid_DoubleClick"
Margin="0 0 0 5">
<DataGrid.Columns>
<!-- Create a column per value. This can be automated by using a template instead. -->
<DataGridTemplateColumn Header="{Binding Path=Item}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=IsSelected,UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
Your ICommand implementation can then just iterate over the collection and set all to selected.
foreach(var item in this.Data)
{
item.IsSelected = true;
}
Upvotes: 1
Reputation: 3451
If not using viewmodel, can you not do this in code behind?
Attach an event handler to the check all checkbox checked state changed event. As long as your controls are all named, they can be interacted with from code behind.
Upvotes: 3