2010-01-29 13 views
5

में डायनामिक बाध्यकारी मुझे WPF में डेटा बाध्यकारी डेटाग्रिड के बारे में कोई प्रश्न है। मैं वीएस 2010 बीटा 2 का उपयोग कर रहा हूं जिसमें इसका अपना डेटाग्रिड है, टूलकिट नहीं, हालांकि मुझे लगता है कि यह काफी समान है।WPF DataGridCell टेम्पलेट

मैं एक डेटासेट से जुड़ना चाहता हूं जिसमें 52 कॉलम हैं, जो वर्ष के हर सप्ताह के लिए एक है। इस कारण से मैं प्रत्येक फ़ील्ड को निर्दिष्ट करने के बजाय डेटा को गतिशील रूप से बांधना चाहता हूं। कुछ स्थितियों के आधार पर प्रत्येक फ़ील्ड का मान सत्य या गलत है। इस मान के आधार पर मैं सेल टेम्पलेट में एक छवि दिखाना चाहता हूं यदि स्थिति सत्य है और यदि स्थिति सत्य नहीं है तो इसे छुपाएं।

मेरी समस्या यह है कि मैंने पाया है कि टेम्पलेट्स का उपयोग करने के सभी उदाहरण निश्चित, पूर्वनिर्धारित फ़ील्ड के मामले को संदर्भित करते हैं, जहां आप टेक्स्ट = "{बाइंडिंग उपयोगकर्ता नाम} जैसे बाध्यकारी हो सकते हैं। यह मेरे लिए अच्छा नहीं है क्योंकि मुझे नहीं पता कि फील्ड नाम डिजाइन समय पर क्या होंगे।

मैंने एक सरलीकृत उदाहरण बनाया है जो समस्या को दर्शाता है। इस उदाहरण में एक डेटा तालिका उत्पन्न होती है जिसमें सत्य और गलत मान होते हैं। मेरे टेम्पलेट में छवि कभी दिखाई नहीं दे रही है। डेटा में सही या गलत मूल्य के आधार पर मैं इसे अदृश्य कैसे बनाऊंगा? पीछे

<Window.Resources> 

    <!--This is the bit that doesn't work...--> 
    <Style TargetType="{x:Type Image}" x:Key="HideWhenFalse"> 
     <Setter Property="Visibility" Value="Hidden" /> 
     <Style.Triggers> 
      <DataTrigger 
     Binding="{Binding Path=???}" 
     Value="True"> <!--What to put for the path? --> 
       <Setter Property="Visibility"> 
        <Setter.Value> 
         Visible 
        </Setter.Value> 
       </Setter> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
    <!--Up to here--> 

    <Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <StackPanel> 
         <Image Source="Images/tick.bmp" Style="{StaticResource HideWhenFalse}"> 

         </Image> 
        </StackPanel> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 

<Grid> 
    <DataGrid 
     x:Name="myDataGrid" 
     AutoGenerateColumns="True" > 

    </DataGrid> 
</Grid> 

कोड:

सार्वजनिक आंशिक वर्ग MainWindow: विंडो {

public MainWindow() 
{ 
    InitializeComponent(); 

    DataTable dtTable = new DataTable(); 

    dtTable.Columns.Add("A", typeof(Boolean)); 
    dtTable.Columns.Add("B", typeof(Boolean)); 
    dtTable.Columns.Add("C", typeof(Boolean)); 
    dtTable.Columns.Add("D", typeof(Boolean)); 
    dtTable.Columns.Add("E", typeof(Boolean)); 
    dtTable.Columns.Add("F", typeof(Boolean)); 

    for (int i = 0; i < 5; i++) 
    { 
     object[] oValues = new Object[dtTable.Columns.Count]; 

     for (int j = 0; j < dtTable.Columns.Count; j++) 
     { 
      oValues[j] = (j % 2 == 1) ? true : false; 
     } 

     dtTable.Rows.Add(oValues); 
    } 

    myDataGrid.ItemsSource = dtTable.DefaultView; 
    myDataGrid.Items.Refresh(); 
} 

}

एनबी यह शायद स्पष्ट है और मैं पूरी तरह से गलत तरीके से समस्या का सामना कर रहा हूं। यहां एक कबुलीजबाब है: मैं अब कुछ महीनों के लिए डब्ल्यूपीएफ के आसपास अपना सिर लेने की कोशिश कर रहा हूं और मुझे लगता है कि मैं खुद को गलत तरीके से हर समस्या का सामना कर रहा हूं। मुझे उम्मीद है कि पैसा जल्द ही गिर जाएगा।

उत्तर

9

आप MultiBinding का उपयोग कर सकते हैं, जिसमें पहले बाध्यकारी सेल से वास्तविक डेटा संदर्भ (जो पंक्ति होगी) लेते हैं, और दूसरा कॉलम लेता है। वहां से, आप सेल मान पुनर्प्राप्त कर सकते हैं।

कनवर्टर कोड:

public class RowColumnToCellConverter : IMultiValueConverter { 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { 
     DataRowView row = values[0] as DataRowView; 
     DataGridColumn column = values[1] as DataGridColumn; 
     return row != null && column != null 
      ? row[column.SortMemberPath] 
      : DependencyProperty.UnsetValue; 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { 
     throw new NotSupportedException(); 
    } 
} 

XAML:

<Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <StackPanel> 
         <TextBlock x:Name="TextOK" Text="OK" Visibility="Collapsed" /> 
        </StackPanel> 
        <ControlTemplate.Triggers> 
         <DataTrigger Value="True"> 
          <DataTrigger.Binding> 
           <MultiBinding Converter="{StaticResource RowColumnToCellConverter}"> 
            <Binding /> 
            <Binding RelativeSource="{x:Static RelativeSource.Self}" Path="Column" /> 
           </MultiBinding> 
          </DataTrigger.Binding> 
          <Setter TargetName="TextOK" Property="Visibility" Value="Visible" /> 
         </DataTrigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

मैं परीक्षण के लिए एक TextBlock बजाय छवि का इस्तेमाल किया है, लेकिन कोड एक ही हो जाएगा। छवि के लिए शैली को परिभाषित करने से बचें अगर इसे DataGridCell की शैली में सीधे किया जा सकता है।

+0

आपके बहुत तेज़ उत्तर, जूलियन के लिए धन्यवाद। यह एक इलाज करता है। – Richard

+1

@ रिचर्ड - आपको यह जवाब स्वीकार करना चाहिए – David

+0

Merci bien, ça m'a beaucoup aidé! – David