In a DataGrid I display a list of items which contain a property IsEnabled which is represented by a datagridviewcheckboxcolumn. I want to limit the number of checkboxes to be checked at the same time to 5.
How could I do that?
Edit:
What I am doing now is using multibinding: the converter accepts the "IsEnabled" property of the items object and the items list itself as input values.
<DataGrid ItemsSource="{Binding MyItems}" AutoGenerateColumns="false"
CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserSortColumns="false">
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="" Binding="{Binding Path=IsEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<DataGridCheckBoxColumn.CellStyle>
<Style>
<Setter Property="CheckBox.IsEnabled" >
<Setter.Value>
<MultiBinding Converter="{Utilities:MyConverter}">
<Binding Path="IsEnabled" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="DataContext.MyItems" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</DataGridCheckBoxColumn.CellStyle>
</DataGridCheckBoxColumn>
...
The convert function within MyConverterlooks like this:
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var val1 = (bool)values[0];
int numSelected = 0;
if (values[1] != null && values[1] is ObservableCollection<MyTestItem>)
{
var list = (ObservableCollectionBase<MyTestItem>)values[1];
foreach (MyTestItem mti in list)
{
if (mti.IsEnabled)
numSelected++;
}
}
else
{
return false;
}
return val1 ? val1 : (numSelected < 5);
}
This works as expected (no more than 5 checkboxes could be selected at the same time, all others are disabled), but I keep getting warnings like:
System.Windows.Data Warning: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression:Path=DataContext.MyItems; DataItem=null; target element is 'DataGridCell' (Name=''); target property is 'IsEnabled' (type 'Boolean')
I also tried to set the datagrids name and use "ElementName" in the binding, but I keep getting the same warnings, although the behaviour is correct.
Why do I get these warnings?
Add an event handler to the checkbox checked event. Check the underlying data source's records to see how many are already checked, and cancel the checked event if it is greater than 5 records.