【问题标题】:wpf datagridcheckboxcolumn: how to enable/disable checkboxeswpf datagridcheckboxcolumn:如何启用/禁用复选框
【发布时间】:2013-10-11 05:36:25
【问题描述】:

我有一个DataGridDataGridCheckBoxColumn。网格具有与对象列表的绑定。我想要的是,如果选中了 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");
    }
}

【问题讨论】:

    标签: c# wpf checkbox datagrid


    【解决方案1】:

    感谢 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完整话题

    【讨论】:

    • 两年后我想说声谢谢,因为这解决了我遇到的另一个问题。 DataGrid.Columns 不是 WPF 中设计树的一部分,所以当你有绑定时,比如在复选框列上,你不能在说...主窗口上进行 RelativeSource AncestorType 搜索。所以你不能绑定到窗口的数据上下文,你必须绑定到数据网格的数据上下文,这在某些情况下可能会有所不同。但是,您将样式放在数据网格资源中的解决方案允许将相对源绑定到窗口,因此复选框列现在可以通过代理绑定到它!
    【解决方案2】:

    是的,您可以在 Triggers 的帮助下做到这一点,就像这样

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

    您可以将此样式应用于您的复选框

    【讨论】:

    • 添加样式会改变我的 datagridcheckboxcolumn 中复选框的行为...所有复选框都不居中,但是,双击单元格容器后,它们会神奇地返回单元格的中心...只要我选择另一个单元格
    【解决方案3】:

    您可以将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" />
                             <EventSetter
                        </Style>
                    </DataGridCheckBoxColumn.ElementStyle>
                </DataGridCheckBoxColumn>
            </DataGrid.Columns>
        </DataGrid>
    
    
    
     private bool hasMaxNumberReached;
     public bool HasMaxNumberReached
     {
      get 
         {return hasMaxNumberReached;}
      set 
         {
          hasMaxNumberReached =value; 
           RaisePropertyChanged("HasMaxNumberReached");
           }
      }
    

    【讨论】:

    • 所以不需要通过代码做任何事情(不包括HAsMaxNumberReached管理)?
    • 但是这样我只能禁用未选中的吗?
    • 我已经尝试过代码。 TargetType="DataGridCell" 不起作用,引发异常。如果我将其更改为 CheckBox,则不会触发事件 CellEditEnding...
    • @Farzi 它可以工作,但是我更改 HasMaxNumberReached 值的事件 CellEditEnding 永远不会被触发......加上复选框被选中/取消选中,仅单击包含复选框的单元格,不同于以前的行为,其中复选框被选中/取消选中,只点击复选框...
    • @nit 你需要建议我在哪里更新 HasMaxNumberReached 的值,因为在我使用事件 CellEditEnding 之前,现在这个事件永远不会被触发
    猜你喜欢
    • 2019-03-31
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 2019-03-04
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多