6

I have a DataGrid with DataGridCheckBoxColumn. The grid has a binding with a list of objects. I want that, if there are N checkboxes checked, the unchecked become disabled, but I don't know how to perform the disable.

<DataGridCheckBoxColumn
    x:Name="IsFixedByBracketColumn"
    Header="Fissato con staffa"
    Binding="{Binding isFixedByBracket, UpdateSourceTrigger=PropertyChanged}"
    IsReadOnly="False">
    <DataGridCheckBoxColumn.ElementStyle>
        <Style TargetType="CheckBox">
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition
                            Binding="{Binding
                                HasMaxNumberReached,
                                RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                            Value="true"/>
                        <Condition
                            Binding="{Binding
                                IsChecked,
                                RelativeSource={RelativeSource Self}}"
                            Value="false"/>
                    </MultiDataTrigger.Conditions>
                    <Setter Property="IsEnabled" Value="False"/>
                </MultiDataTrigger>
            </Style.Triggers>
            <EventSetter
                Event="CheckBox.Checked"
                Handler="DataGridCheckBoxColumn_Checked" />
        </Style>
    </DataGridCheckBoxColumn.ElementStyle>                                        
</DataGridCheckBoxColumn>

Code for the event:

private void DataGridCheckBoxColumn_Checked(object sender, RoutedEventArgs e)
{
    CheckBox cb = (CheckBox)sender;
    if (cb.IsChecked == true)
    {
        this.numberOfCheckboxesChecked++;
    }
    else
    {
        this.numberOfCheckboxesChecked--;
    }

    if (this.numberOfCheckboxesChecked >= maxNumOfPointsPerSide)
    {               
        this.HasMaxNumberReached = true;
    }
    else 
    {
        this.HasMaxNumberReached = false; 
    }              
}

public bool HasMaxNumberReached
{
    get {
        return hasMaxNumberReached;
    }
    set { 
        hasMaxNumberReached = value; 
        RaisePropertyChanged("HasMaxNumberReached");
    }
}

3 Answers 3

3

Thanks to Magnus in MSDN Forum, here is the correct answer of the problem:

<DataGrid x:Name="grid" AutoGenerateColumns="False">
        <DataGrid.Resources>
            <Style TargetType="CheckBox" x:Key="style">
                <Style.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding HasMaxNumberReached, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Value="true"/>
                            <Condition Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="false"/>
                        </MultiDataTrigger.Conditions>
                        <Setter Property="IsEnabled" Value="False"/>
                    </MultiDataTrigger>
                </Style.Triggers>
                <EventSetter Event="CheckBox.Checked" Handler="DataGridCheckBoxColumn_Checked" />
                <EventSetter Event="CheckBox.Unchecked" Handler="DataGridCheckBoxColumn_Checked" />
            </Style>
        </DataGrid.Resources>
        <DataGrid.Columns>
        <DataGridCheckBoxColumn x:Name="IsFixedByBracketColumn"  Header="Fissato con staffa" 
                                Binding="{Binding isFixedByBracket, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False"
                                ElementStyle="{StaticResource style}" EditingElementStyle="{StaticResource style}">

        </DataGridCheckBoxColumn>
        </DataGrid.Columns>
    </DataGrid> 

Here the complete topic

Sign up to request clarification or add additional context in comments.

1 Comment

Two years later I want to say thank you because this solved a different issue I was having. DataGrid.Columns is not part of the design tree in WPF so when you have bindings, like on the checkboxcolumn, you can't do a RelativeSource AncestorType search on say... the main window. So you can't bind to the window's datacontext, you have to bind to the datagrid's datacontext which can be different in certain situations. HOWEVER your solution of putting the style in the datagrid resources allow for the relative source to be bound to the window, thus the checkbox column can now bind to it via proxy!
0

Yes you can do it with the help of Triggers, like this

<Style x:Key="MyCheckBoxStyle" TargetType="{x:Type CheckBox}">  
 <Style.Triggers>
  <Trigger Property="IsChecked" Value="False">
   <Setter Property="IsEnabled" Value="False" />
 </Trigger>
</Style.Triggers>

and you can apply this style to your checkbox

1 Comment

adding styles changes the behaviour of checkboxes in my datagridcheckboxcolumn...all checkboxes are not centered but, after double click on cell container, they returns magically on center of the cell...as long as I select another cell
0

you can set DataGridCheckBoxColumn.ElementStyle to enable/disable cell as explained below. Here assuming HasMaxNumberReached is a property on your ViewModel which tell that the count of max checkbox checked has reached.

  <DataGrid>
        <DataGrid.Columns>
            <DataGridCheckBoxColumn>
                <DataGridCheckBoxColumn.ElementStyle>
                    <Style TargetType="Checkbox">
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding HasMaxNumberReached, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Value="true"/>
                                    <Condition Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="false"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="IsEnabled" Value="False"/>
                            </MultiDataTrigger>                               
                        </Style.Triggers>
                        <EventSetter
                              Event="CheckBox.Checked"
                               Handler="DataGridCheckBoxColumn_Checked" />
                    </Style>
                </DataGridCheckBoxColumn.ElementStyle>
            </DataGridCheckBoxColumn>
        </DataGrid.Columns>
    </DataGrid>



 private bool hasMaxNumberReached;
 public bool HasMaxNumberReached
 {
  get 
     {return hasMaxNumberReached;}
  set 
     {
      hasMaxNumberReached =value; 
       RaisePropertyChanged("HasMaxNumberReached");
       }
  }

13 Comments

so it is not needed to do anything via code (excluding HAsMaxNumberReached management)?
but in this way do I disable only the unchecked one?
I've tried the code. TargetType="DataGridCell" does not work, raises an exception. If I change it to CheckBox, the event CellEditEnding is not fired...
@Farzi it works, but the event CellEditEnding in which I change the value of HasMaxNumberReached is never fired...plus the checkbox is checked/unchecked only clicking in the cell that contains the checkbox, differing from previous behaviour in which the checkbox is checked/unchecked clicking only on checkbox...
@nit you need to suggest me where must I update the value of HasMaxNumberReached , because before I've used the event CellEditEnding , and now this event is never fired
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.