2013-08-31 9 views
5

मेरे एमवीवीएम में, मेरे पास एक डेटाग्रिड है जहां मैं पंक्ति मानकों को 2 मानदंडों के आधार पर सक्षम करना चाहता हूं। डेटाग्रिड में 1 कॉल में चेकबॉक्स है (जो IsRowchecked प्रॉपर्टी से जुड़ा हुआ है) और किसी अन्य कॉल में हेडर चेकबॉक्स है। मैं पंक्ति तत्व को सक्षम करना चाहता हूं यदि 1) IsRowchecked सत्य है और 2) शीर्षलेख चेकबॉक्स चयनित है।एकाधिक मानदंडों पर WPF बाध्यकारी

क्या यह एकाधिक मानदंड सेटिंग संभव है?

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 को 2 मानदंडों की आवश्यकता है यानी IsRow चेक किए गए और हेडर चेकबॉक्स का चयन किया गया है। मैं एकल के साथ कर सकता था, लेकिन इन बाइंडिंग में 2 मानदंडों को लागू करने का कोई तरीका नहीं मिल सकता है।

मैं इस तरह के बाध्यकारी कैसे प्राप्त कर सकता हूं ???

किसी भी मदद की अत्यधिक सराहना की जाती है।

धन्यवाद

उत्तर

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

यह विधि तब काम करती है जब केवल एक संपत्ति मान कॉन्फ़िगरेशन को विशिष्ट व्यवहार की आवश्यकता होती है। आपके उदाहरण में, टेक्स्ट बॉक्स हमेशा अक्षम रहता है, सिवाय जब चेक बॉक्स चेक किए जाते हैं। वाक्यविन्यास अधिक जटिल है, लेकिन कन्वर्टर्स की आवश्यकता नहीं है।

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

वाह Athari, दोनों विकल्पों बिल्कुल ठीक काम कर रहे हैं। मैं सोच रहा हूं कि किस का उपयोग करना है। इस मामले में, मुझे लगता है कि मैं केवल मल्टीबाइंडिंग के साथ जाऊंगा। एक और सवाल, क्या मैं इसे अपने शीर्षलेख चेकबॉक्स पर लागू कर सकता हूं - यदि Value1 हेडर chkbox चुना गया है, तो केवल उपयोगकर्ता को Value2 हेडर चेकबॉक्स का चयन करने दें। प्रारंभ में Value2 हेडर chkbox अक्षम किया जा सकता है, और जब उपयोगकर्ता Value1 chkValue1 का चयन करता है, तो केवल chkValue2 को सक्षम करें। क्या इसे हेडर चेकबॉक्स में कार्यान्वित किया जा सकता है ??? – Tvd

+0

@Tvd मुझे सटीक बुलियन अभिव्यक्तियों को समझ में नहीं आया, लेकिन किसी भी मामले में, आप कनवर्टर के साथ 'मल्टीबाइंडिंग' का उपयोग कर सकते हैं। एक 'मल्टी बाइंडिंग' में 'बाध्यकारी' की संख्या हो सकती है, जिनसे मूल्य 'IMultiValueConverter.Convert' विधि को 'मान' तर्क में पारित किया जाता है। इस विधि के अंदर, आप जो भी तार्किक अभिव्यक्ति चाहते हैं उसे लिख सकते हैं। कोड जो मैंने कनवर्ट किया है, वह थोड़ा जटिल है, क्योंकि यह सामान्य है और सभी संभावनाओं की जांच करता है, लेकिन मूल रूप से यह 'वापसी (बूल) मान [0] && (बूल) मान [1] 'है। – Athari

संबंधित मुद्दे