2013-08-31 44 views
5

Trong MVVM của tôi, theo quan điểm tôi có một DataGrid nơi tôi muốn cho phép các yếu tố hàng dựa trên 2 tiêu chí. DataGrid có hộp kiểm trong 1 col (được ràng buộc với thuộc tính IsRowChecked) và hộp kiểm tiêu đề trong một col khác. Tôi muốn kích hoạt phần tử hàng nếu 1) IsRowChecked là true AND 2) Hộp kiểm đầu trang được chọn.WPF Binding trên nhiều tiêu chí

Có thể thiết lập nhiều tiêu chí này không?

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> 

"Số Hóa chất" col cần chỉ tiêu chí đơn ràng buộc mà tôi có thể làm. Value1 & Value2 cần 2 tiêu chí, nghĩa là hộp kiểm IsRowChecked và tiêu đề được chọn. Tôi có thể làm với duy nhất, nhưng không thể có được một cách để thực hiện 2 tiêu chí trong các ràng buộc này.

Làm thế nào tôi có thể đạt được loại ràng buộc này ???

Mọi trợ giúp đều được đánh giá cao.

Cảm ơn

Trả lời

7

Có hai cách để làm việc với các biểu thức phức tạp vào sự liên kết: MultiBinding với bộ chuyển đổi và MultiDataTrigger với trường hợp cụ thể. Ví dụ của bạn, cả hai đều hoạt động tốt.

1. MultiBinding

Phương pháp này làm việc cho hầu như mọi trường hợp, nhưng đòi hỏi phải thực hiện chuyển đổi (họ có thể được tái sử dụng, rõ ràng).

  1. Tạo AndConverter lớp triển khai IMultiValueConverter giao diện. Nó cần phải trả lại true nếu tất cả các giá trị được chuyển đến đúng là (DependencyProperty.UnsetValue là một giá trị đặc biệt khi không có giá trị).

    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. Thêm công cụ chuyển đổi các nguồn lực:

    <Window.Resources> 
        <local:AndConverter x:Key="convAnd"/> 
    </Window.Resources> 
    
  3. Chỉ định DataTemplate cho Value1 cột (mã gốc là nhận xét):

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

Phương pháp này hoạt động khi chỉ có một cấu hình giá trị thuộc tính cần hành vi cụ thể. Trong ví dụ của bạn, hộp văn bản luôn bị tắt, trừ khi chọn cả hai hộp kiểm. Cú pháp phức tạp hơn, nhưng không cần chuyển đổi.

  1. Chỉ định DataTemplate cho Value2 cột (mã gốc là nhận xét):

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

Wow Athari cả các tùy chọn được làm việc hoàn toàn tốt đẹp. Đang tự hỏi nên sử dụng cái nào. Trong trường hợp này, tôi nghĩ rằng tôi sẽ đi với MultiBinding chỉ. Một câu hỏi nữa, Tôi có thể thực hiện tương tự trên Hộp kiểm đầu trang của tôi - Nếu chkbox tiêu đề Value1 được chọn, thì chỉ cho phép người dùng chọn hộp kiểm tiêu đề Value2. Ban đầu Value2 tiêu đề chkbox bị vô hiệu hóa, và khi người dùng chọn Value1 chkValue1, thì chỉ bật chkValue2. Điều này có thể được thực hiện trong hộp kiểm đầu trang không ??? – Tvd

+0

@Tvd Tôi không hiểu các biểu thức chính xác của boolean, nhưng trong mọi trường hợp, bạn có thể sử dụng 'MultiBinding' với trình chuyển đổi. 'MultiBinding' có thể chứa bất kỳ số lượng' Binding' nào, các giá trị từ đó được chuyển trong một đối số 'values' sang phương thức' IMultiValueConverter.Convert'. Bên trong phương thức này, bạn có thể viết bất kỳ biểu thức logic nào bạn muốn. Mã tôi đã sử dụng trong 'Chuyển đổi 'là một phức tạp chút, vì nó là chung và kiểm tra tất cả các khả năng, nhưng về cơ bản nó là' các giá trị trả về (bool) [0] && (bool) [1] '. – Athari