WPF DataGridCheckboxColumn:如何启用/禁用复选框

6

我有一个带有DataGridCheckBoxColumnDataGrid。该表格与对象列表绑定。如果有N个复选框被选中,我希望未选中的变为禁用状态,但我不知道如何实现禁用。

<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>

活动代码:

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个回答

3
感谢 MSDN 论坛中的 Magnus,以下是该问题的正确答案:
<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


两年后,我想说谢谢,因为这解决了我遇到的另一个问题。在WPF中,DataGrid.Columns不属于设计树,因此当您有绑定(例如复选框列)时,就无法在RelativeSource AncestorType搜索中使用主窗口。因此,您不能绑定到窗口的数据上下文,而必须绑定到数据网格的数据上下文,这在某些情况下可能是不同的。但是,将样式放在数据网格资源中的您的解决方案允许相对源绑定到窗口,因此通过代理现在可以将复选框列绑定到它! - user99999991

0

您可以设置DataGridCheckBoxColumn.ElementStyle来启用/禁用单元格,如下所述。这里假设HasMaxNumberReached是ViewModel上的一个属性,它告诉我们已经达到了最大选中复选框的数量。

  <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");
       }
  }

因此,除了HAsMaxNumberReached管理之外,不需要通过代码执行任何操作吗? - FrancescoDS
但是这样做,我只禁用未选中的那个吗? - FrancescoDS
我已经尝试了这段代码。TargetType="DataGridCell" 无法工作,会引发异常。如果我将其更改为 CheckBox,则事件 CellEditEnding 将无法触发... - FrancescoDS
如果你在谈论我上面描述的事件,是的,它总是被触发。 - FrancescoDS
@nit 我在哪里可以找到一些关于它的教程? - FrancescoDS
显示剩余8条评论

0

你可以通过触发器来实现,像这样

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

你可以将这种样式应用于你的复选框


添加样式会改变我的DataGridCheckBoxColumn中复选框的行为...所有复选框都不居中,但是,在双击单元格容器后,它们会神奇地返回到单元格的中心...只要我选择另一个单元格。 - FrancescoDS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接