5

在我的 MVVM 中,鉴于我有一个 DataGrid,我想在其中启用基于 2 个条件的行元素。DataGrid 在 1 col 中有复选框(绑定到 IsRowChecked 属性),在另一个 col 中有一个标题复选框。如果 1) IsRowChecked 为真并且 2) 选中了标题复选框,我想启用行元素。

这种多重标准设置可能吗?

XAML

<DataGrid ItemsSource="{Binding SiList, Mode=TwoWay}" Name="dgvSiSelection">
      <DataGrid.Columns>                  
          <DataGridCheckBoxColumn Binding="{Binding IsRowChecked, Mode=TwoWay}"/>  
          <DataGridTextColumn Header="" Binding="{Binding Header}" MinWidth="108" IsReadOnly="True"/>
          <DataGridTemplateColumn>
              <DataGridTemplateColumn.Header>
                    <Grid>
                        <Grid.ColumnDefinitions>
                              <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="Number of Chemicals" Grid.Column="0"  />
                    </Grid>                                        
               </DataGridTemplateColumn.Header>
               <DataGridTemplateColumn.CellTemplate>
                     <DataTemplate>
                          <TextBlock Text="{Binding Path=NumberOfCases}" />
                     </DataTemplate>
                     </DataGridTemplateColumn.CellTemplate>
                     <DataGridTemplateColumn.CellEditingTemplate>
                          <DataTemplate>
                              <TextBox IsEnabled="{Binding Path=IsRowChecked}" Text="{Binding Path=NumberOfCases, Mode=TwoWay}" />
                         </DataTemplate>
                     </DataGridTemplateColumn.CellEditingTemplate>
                 </DataGridTemplateColumn>


                 <!-- Value1  chkValue11-->
                 <DataGridTemplateColumn>
                     <DataGridTemplateColumn.Header>
                          <Grid>
                              <Grid.ColumnDefinitions>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                              </Grid.ColumnDefinitions>
                              <TextBlock Grid.Column="1" Text="Value1" IsEnabled="{Binding ElementName=chkValue11, Path=IsChecked}" />
                              <CheckBox Name="chkValue11"  Grid.Column="0" Width="16" />
                          </Grid>
                     </DataGridTemplateColumn.Header>
                     <DataGridTemplateColumn.CellTemplate>
                          <DataTemplate>
                                <TextBlock Text="{Binding Path=Value1}" />
                          </DataTemplate>
                     </DataGridTemplateColumn.CellTemplate>
                     <DataGridTemplateColumn.CellEditingTemplate>
                            <DataTemplate>
                                 <TextBox IsEnabled="{Binding ElementName=chkValue11, Path=IsChecked}" Text="{Binding Path=Value1, Mode=TwoWay}" />
                            </DataTemplate>
                      </DataGridTemplateColumn.CellEditingTemplate>
                  </DataGridTemplateColumn>

                  <!-- Value2  chkValue12-->
                  <DataGridTemplateColumn>
                      <DataGridTemplateColumn.Header>
                          <Grid>
                              <Grid.ColumnDefinitions>
                                   <ColumnDefinition/>
                                   <ColumnDefinition/>
                              </Grid.ColumnDefinitions>
                              <TextBlock Grid.Column="1" Text="Value2" IsEnabled="{Binding ElementName=chkValue12, Path=IsChecked}" />
                              <CheckBox Name="chkValue12"  Grid.Column="0" Width="16" />
                          </Grid>
                    </DataGridTemplateColumn.Header>
                    <DataGridTemplateColumn.CellTemplate>
                         <DataTemplate>
                                <TextBlock Text="{Binding Path=Value2}" />
                         </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                          <DataTemplate>
                               <TextBox IsEnabled="{Binding ElementName=chkValue12, Path=IsChecked}" Text="{Binding Path=Value2, Mode=TwoWay}" />
                          </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>

       </DataGrid.Columns>
   </DataGrid>

“化学品数量”列只需要我可以做的单一标准绑定。Value1 & Value2 需要 2 个标准,即 IsRowChecked 和选中的标题复选框。我可以使用单个,但无法在这些绑定中实现 2 个标准。

我怎样才能实现这种绑定???

非常感谢任何帮助。

谢谢

4

1 回答 1

8

有两种方法可以处理绑定上的复杂表达式:MultiBinding使用转换器和MultiDataTrigger特定情况。对于您的示例,两者都可以很好地工作。

1. 多重绑定

这种方法几乎适用于任何情况,但需要实现转换器(它们显然可以重复使用)。

  1. 创建AndConverter类实现IMultiValueConverter接口。true如果传递给它的所有值都为真,则它需要返回(DependencyProperty.UnsetValue当值不可用时是一个特殊值)。

    public class AndConverter : IMultiValueConverter
    {
        public object Convert (object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values.Any(v => ReferenceEquals(v, DependencyProperty.UnsetValue)))
                return DependencyProperty.UnsetValue;
            return values.All(System.Convert.ToBoolean);
        }
    
        public object[] ConvertBack (object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
    
  2. 将转换器添加到资源:

    <Window.Resources>
        <local:AndConverter x:Key="convAnd"/>
    </Window.Resources>
    
  3. 指定DataTemplateValue1(原始代码已注释):

    <DataTemplate DataType="local:Item">
        <!--<TextBox IsEnabled="{Binding ElementName=chkValue11, Path=IsChecked}" Text="{Binding Path=Value1, Mode=TwoWay}"/>-->
        <TextBox Text="{Binding Path=Value1, Mode=TwoWay}">
            <TextBox.IsEnabled>
                <MultiBinding Converter="{StaticResource convAnd}">
                    <Binding ElementName="chkValue11" Path="IsChecked"/>
                    <Binding Path="IsRowChecked"/>
                </MultiBinding>
            </TextBox.IsEnabled>
        </TextBox>
    </DataTemplate>
    

2. 多数据触发器

当只有一个属性值配置需要特定行为时,此方法有效。在您的示例中,文本框始终处于禁用状态,除非选中两个复选框。语法更复杂,但不需要转换器。

  1. 指定DataTemplateValue2(原始代码已注释):

    <DataTemplate DataType="local:Item">
        <!--<TextBox IsEnabled="{Binding ElementName=chkValue12, Path=IsChecked}" Text="{Binding Path=Value2, Mode=TwoWay}"/>-->
        <TextBox x:Name="txt" Text="{Binding Path=Value2, Mode=TwoWay}"
                 IsEnabled="False"/>
        <DataTemplate.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsChecked, ElementName=chkValue12}" Value="True"/>
                    <Condition Binding="{Binding IsRowChecked}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter TargetName="txt" Property="IsEnabled" Value="True"/>
            </MultiDataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
    
于 2013-08-31T14:30:37.280 回答