WPF绑定多个标准

本文关键字:标准 绑定 WPF | 更新日期: 2023-09-27 18:29:40

在我的MVVM中,在视图中,我有一个DataGrid,我希望在其中基于2个条件启用行元素。DataGrid在1列中有复选框(绑定到IsRowChecked属性),在另一列中有表头复选框1) IsRowChecked为true AND2) 选中标题复选框。

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

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只需要单一的标准绑定,我可以做到。Value1&Value2需要两个条件,即IsRowChecked和header复选框选中。我可以使用single,但无法在这些绑定中实现2个条件。

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

非常感谢您的帮助。

感谢

WPF绑定多个标准

有两种方法可以处理绑定上的复杂表达式:使用转换器的MultiBinding和使用特定事例的MultiDataTrigger。举个例子,两者都很好。

1.多绑定

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

  1. 创建实现IMultiValueConverter接口的AndConverter类。如果传递给它的所有值都为true,则它需要返回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. Value1列指定DataTemplate(注释原始代码):

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

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