WPF绑定多个标准

时间:2013-08-31 11:20:48

标签: c# .net wpf mvvm binding

在我的MVVM中,在视图中我有一个DataGrid,我想根据2个条件启用行元素。 DataGrid在1 col中有一个复选框(绑定到IsRowChecked属性),另一个col中有一个header复选框。我想启用row元素if 1)IsRowChecked是真的AND 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>

“化学品数量”col只需要我可以做的单一标准绑定。价值1&amp; Value2需要2个标准,即选择IsRowChecked和标题复选框。我可以使用single,但无法在这些绑定中实现2个条件。

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

非常感谢任何帮助。

由于

1 个答案:

答案 0 :(得分:7)

在绑定上使用复杂表达式有两种方法:MultiBinding带转换器,MultiDataTrigger带特定情况。对于你的例子,两者都很好地工作。

<强> 1。 MultiBinding

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

  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. DataTemplate列指定Value1(原始代码已注释):

    <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>
    
  4. <强> 2。 MultiDataTrigger

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

    1. DataTemplate列指定Value2(原始代码已注释):

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