7

मैंने एक डेटा टेम्पलेट चयनकर्ता बनाया है जिसे ज्ञात इंटरफेस के संग्रह के साथ शुरू किया गया है। यदि चयनकर्ता में पारित कोई आइटम उन इंटरफेस में से एक लागू करता है, तो संबंधित डेटा टेम्पलेट वापस कर दिया जाता है।डेटा टेम्पलेट एक इंटरफ़ेस से क्यों नहीं जुड़ सकता है जब उस डेटा टेम्पलेट को डेटा टेम्पलेट चयनकर्ता से स्पष्ट रूप से वापस कर दिया गया था?

सबसे पहले, यहाँ सवाल में ICategory इंटरफेस है ...

public interface ICategory 
{ 
    ICategory ParentCategory { get; set; } 
    string Name   { get; set; } 

    ICategoryCollection Subcategories { get; } 
} 

यहाँ DataTemplateSelector जो एक आधार वर्ग या बल्कि सिर्फ एक विशिष्ट ठोस वर्ग की तुलना में इंटरफ़ेस के आधार पर मैच है ...

[ContentProperty("BaseTypeMappings")] 
public class SubclassedTypeTemplateSelector : DataTemplateSelector 
{ 
    private delegate object TryFindResourceDelegate(object key); 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     var frameworkElement = container as FrameworkElement; 

     foreach(var baseTypeMapping in BaseTypeMappings) 
     { 
      // Check if the item is an instance of, a subclass of, 
      // or implements the interface specified in BaseType 
      if(baseTypeMapping.BaseType.IsInstanceOfType(item)) 
      { 
       // Create a key based on the BaseType, (not item.DataType as usual) 
       var resourceKey = new DataTemplateKey(baseTypeMapping.BaseType); 

       // Get TryFindResource method from either the FrameworkElement, 
       // or from the application 
       var tryFindResource = (frameworkElement != null) 
        ? (TryFindResourceDelegate)frameworkElement.TryFindResource 
        : Application.Current.TryFindResource; 

       // Use the TryFindResource delegate from above to try finding 
       // the resource based on the resource key 
       var dataTemplate = (DataTemplate)tryFindResource(resourceKey); 
       dataTemplate.DataType = item.GetType(); 
       if(dataTemplate != null) 
        return dataTemplate; 
      } 
     } 

     var defaultTemplate = DefaultDataTemplate ?? base.SelectTemplate(item, container); 
     return defaultTemplate; 
    } 

    public DataTemplate DefaultDataTemplate { get; set; } 

    public Collection<BaseTypeMapping> BaseTypeMappings { get; } = new Collection<BaseTypeMapping>(); 
} 

public class BaseTypeMapping 
{ 
    public Type BaseType { get; set; } 
} 

यहां बताया गया है कि यह संबंधित टाइपराइक्लिक डेटाटाम्प्लेट के साथ डेटाटाइप = आईसीजीई के साथ संसाधनों में कैसे स्थापित किया गया है ...

<HierarchicalDataTemplate DataType="{x:Type model:ICategory}" 
     ItemsSource="{Binding Subcategories}"> 

     <TextBlock Text="{Binding Name}" /> 

    </HierarchicalDataTemplate> 

    <is:SubclassedTypeTemplateSelector x:Key="SubclassedTypeTemplateSelector"> 
     <!--<is:BaseTypeMapping BaseType="{x:Type model:ICategory}" />--> 
    </is:SubclassedTypeTemplateSelector> 

और अंत में, यहाँ एक TreeView जो इसे इस्तेमाल करता है ...

<TreeView x:Name="MainTreeView" 
    ItemsSource="{Binding Categories}" 
    ItemTemplateSelector="{StaticResource SubclassedTypeTemplateSelector}" /> 

मैं इसे डिबग है और पुष्टि कर सकते हैं सही डेटा टेम्पलेट TreeView को लौट जा रही है दोनों के माध्यम से कदम के रूप में उम्मीद कोड और ट्री व्यू आइटमशोर्स बाध्यकारी के अनुसार HierarchicalDataTemplate पर उपश्रेणियों को ठीक से लोड कर रहा है। यह सब अपेक्षित के रूप में काम करता है।

टेम्पलेट की सामग्री स्वयं काम नहीं करती है। जैसा कि आप देख सकते हैं, टेम्पलेट को केवल श्रेणी का नाम दिखाना चाहिए, लेकिन यह केवल ऑब्जेक्ट को कच्चे पेश कर रहा है जैसे कि इसे सीधे किसी सामग्री टेम्पलेट के बिना किसी सामग्री टेम्पलेट में रखा गया हो। यूआई में आप जो कुछ देखते हैं वह टूस्ट्रिंग का परिणाम है। टेम्पलेट की सामग्री पूरी तरह से अनदेखा कर रहे हैं।

एकमात्र चीज जिसे मैं सोच सकता हूं वह काम नहीं कर रहा है क्योंकि मैं डेटाटाइप के लिए एक इंटरफेस का उपयोग कर रहा हूं, लेकिन फिर, बच्चों के आइटम्ससोर्स के लिए बाध्यकारी काम करता है, इसलिए मैं यहां फंस गया हूं।

नोट: एक परीक्षण के रूप में, मैंने कंक्रीट प्रकार (यानी श्रेणी और न केवल आईसीईआरई) के आधार पर दूसरा डेटा टेम्पलेट बनाया और जब मैंने किया, तो यह अपेक्षा के अनुसार काम करता था। समस्या यह है कि ठोस प्रकार एक असेंबली में है जिसे यूआई द्वारा संदर्भित नहीं किया जाना चाहिए। यही कारण है कि हम पहले स्थान पर इंटरफेस का उपयोग कर रहे हैं।

* नोट: मैंने डेटाटाइप संपत्ति को सेट करने के बजाय एक कुंजी का उपयोग करके टेम्पलेट को देखने के तरीके को बदलने का भी प्रयास किया है। उस स्थिति में, जैसा कि पहले है, चयनकर्ता अभी भी वही संसाधन पाता है, लेकिन यह अभी भी काम नहीं करता है!

विडंबना यह है कि हालांकि, अगर मैं का उपयोग एक ही कुंजी, बाध्यकारी एक StaticResource के माध्यम से सीधे TreeView का ItemTemplate स्थापित करने के लिए है कि तब यह करता काम, जिसका अर्थ यह केवल जब मैं चयनकर्ता से टेम्पलेट लौट काम नहीं करता है और करता है डेटाटाइप सेट या नहीं है या नहीं संबंधित से संबंधित दिखाई देता है।*

+0

संक्षिप्त उत्तर: क्योंकि यह इस तरह से डिज़ाइन किया गया है। शायद क्योंकि आप एक वर्ग के लिए कई मैच प्राप्त कर सकते हैं। [एमएसडीएन पर आधिकारिक उत्तर] (https://social.msdn.microsoft.com/Forums/vstudio/en-US/1e774a24-0deb-4acd-a719-32abd847041d/data-templates-and-interfaces?forum=wpf) –

+0

यदि आप अपने एमएसडीएन लिंक को देखते हैं, तो आप देखेंगे कि वे विशेष रूप से कहते हैं कि आप डेटा टेम्पलेट चयनकर्ता का उपयोग कर सकते हैं, जो मैं ऊपर कर रहा हूं। आपका तर्क, और वे जो कहते हैं, उनके खिलाफ उन्होंने फैसला किया है कि वे स्वयं इंटरफ़ेस से मिलान करने की कोशिश कर रहे हैं, जो कि मैं यहां हासिल करने की कोशिश नहीं कर रहा हूं। – MarqueIV

+0

आपका मूल प्रश्न था "डेटा टेम्पलेट इंटरफ़ेस से क्यों नहीं जुड़ सकता?"। मैंने सोचा था कि आप रुचि रखते थे कि यह क्यों है। –

उत्तर

1

क्या काम नहीं करता है स्वयं टेम्पलेट को

इसका कारण यह है टेम्पलेट्स है कि आप अपने XAML मार्कअप में परिभाषित के बाद से डेटा प्रकार गुण के लिए सेट है लागू नहीं किया जा रहा है की सामग्री है एक इंटरफ़ेस प्रकार। जैसा कि @ मॅनफ्रेड रैड्लविमर सुझाव देते हैं कि यह डिज़ाइन द्वारा है: https://social.msdn.microsoft.com/Forums/vstudio/en-US/1e774a24-0deb-4acd-a719-32abd847041d/data-templates-and-interfaces?forum=wpf। DataTemplateSelector से ऐसा टेम्पलेट लौटने से यह काम नहीं करता है जैसा कि आप पहले ही खोज चुके हैं।

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

<HierarchicalDataTemplate x:Key="ICategory" ItemsSource="{Binding Subcategories}"> 
    <TextBlock Text="{Binding Name}" /> 
</HierarchicalDataTemplate> 

फिर आप में सक्षम होना चाहिए संसाधन इस कुंजी का उपयोग कर, जैसे हल:

var baseTypeName = "ICategory"; 
var dataTemplate = (DataTemplate)tryFindResource("baseTypeName"); 
+0

दरअसल, मैंने बिल्कुल कोशिश की और यह भी काम नहीं करता है। विशेष रूप से मैंने डेटाटाइप प्रॉपर्टी को हटा दिया, एक कुंजी जोड़ा, फिर उस कुंजी द्वारा प्राप्त टेम्पलेट लौटा दिया (जो अनिवार्य रूप से आपने जो सुझाव दिया है) और यह अभी भी काम नहीं कर रहा है। हालांकि, अधिक विशिष्ट रूप से, जब मैं उस टेम्पलेट को सीधे TreeView ('{StaticResource ICategory} 'के आइटम टेम्पलेट पर सेट करता हूं, तो यह काम करता है। और फिर, आइटम्ससोर्स बाइंडिंग किसी भी मामले में काम करता है जो मुझे और भी रोक देता है। – MarqueIV

-1
  1. DataTemplates इंटरफेस के उद्देश्य नहीं कर सकते हैं -> किया - तो आप एक चयनकर्ता या एक समाधान की जरूरत है।
  2. तुम सिर्फ उपयोग कर सकते हैं: बजाय लागू करने BaseTypeMapping
  3. उपयोग BaseType.IsAssignableFrom(item.GetType()) की {x प्रकार} जाँच करने के लिए यदि आप एक मैच
  4. है आप से आप टेम्पलेट परिभाषा प्रकार दूर करने के लिए है, यह अगर आपके पास नहीं सौंपा जा सकता है एक गलत प्रकार - तो आप एक कुंजी जोड़ते हैं।
  5. # 4 के बाद आपके टेम्पलेट की एक कुंजी है और यह केवल प्रकार निर्दिष्ट करके अंतर्निहित काम नहीं करती है, इसलिए आपको इसे टाइप करने के बाद इसे हटा देना होगा ->dataTemplate.Key = null
  6. मेरे पास कोई आईडीई नहीं है, लेकिन ढूंढें रिसोर्स आपको एक उदाहरण देता है, इसलिए आप संदर्भ के अनुसार बदलते हैं। क्या आप यही चाहते हैं?
+0

मैं वास्तव में बेसटाइपमैपिंग का उपयोग करता हूं क्योंकि इसमें डेटा टेम्पलेट और डेटा टेम्पलेटकी गुण भी हैं (जिन्हें मैंने यहां से ब्रेवटी के लिए छोड़ा था।) लेकिन इसका उपयोग करके, जिसका अर्थ है कि टेम्पलेट में डेटाटाइप असाइन नहीं है, यह सीधे सेट होने पर काम करता है ItemTemplate लेकिन आइटम टेम्पलेट चयनकर्ता के माध्यम से वापस नहीं आया, यही कारण है कि मैं पूरी तरह से यहां फंस गया हूं, खासकर क्योंकि जैसा कि मैंने कहा था, आइटम्ससोर्स बाध्यकारी * काम करता है। – MarqueIV

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