मैंने एक डेटा टेम्पलेट चयनकर्ता बनाया है जिसे ज्ञात इंटरफेस के संग्रह के साथ शुरू किया गया है। यदि चयनकर्ता में पारित कोई आइटम उन इंटरफेस में से एक लागू करता है, तो संबंधित डेटा टेम्पलेट वापस कर दिया जाता है।डेटा टेम्पलेट एक इंटरफ़ेस से क्यों नहीं जुड़ सकता है जब उस डेटा टेम्पलेट को डेटा टेम्पलेट चयनकर्ता से स्पष्ट रूप से वापस कर दिया गया था?
सबसे पहले, यहाँ सवाल में 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 स्थापित करने के लिए है कि तब यह करता काम, जिसका अर्थ यह केवल जब मैं चयनकर्ता से टेम्पलेट लौट काम नहीं करता है और करता है डेटाटाइप सेट या नहीं है या नहीं संबंधित से संबंधित दिखाई देता है।*
संक्षिप्त उत्तर: क्योंकि यह इस तरह से डिज़ाइन किया गया है। शायद क्योंकि आप एक वर्ग के लिए कई मैच प्राप्त कर सकते हैं। [एमएसडीएन पर आधिकारिक उत्तर] (https://social.msdn.microsoft.com/Forums/vstudio/en-US/1e774a24-0deb-4acd-a719-32abd847041d/data-templates-and-interfaces?forum=wpf) –
यदि आप अपने एमएसडीएन लिंक को देखते हैं, तो आप देखेंगे कि वे विशेष रूप से कहते हैं कि आप डेटा टेम्पलेट चयनकर्ता का उपयोग कर सकते हैं, जो मैं ऊपर कर रहा हूं। आपका तर्क, और वे जो कहते हैं, उनके खिलाफ उन्होंने फैसला किया है कि वे स्वयं इंटरफ़ेस से मिलान करने की कोशिश कर रहे हैं, जो कि मैं यहां हासिल करने की कोशिश नहीं कर रहा हूं। – MarqueIV
आपका मूल प्रश्न था "डेटा टेम्पलेट इंटरफ़ेस से क्यों नहीं जुड़ सकता?"। मैंने सोचा था कि आप रुचि रखते थे कि यह क्यों है। –