2011-09-12 11 views
16

के अंदर DataTemplate के रूप में UserControl मैं अपने UserControls को पृष्ठ या विंडो जैसे डेटा टेम्पलेट्स के रूप में पुन: उपयोग करना चाहता हूं, इस उदाहरण में ListBox के अंदर। सब कुछ एमवीवीएम है।ListCox

मेरे पास एक साधारण ऑब्जेक्ट "कार्ड" प्रदर्शित करने के लिए "कार्डकंट्रोल" नामक उपयोगकर्ता नियंत्रण है। कार्ड में दो गुण हैं, "आईडी" और "कार्ड इमेज"। नियंत्रण डेटाकॉन्टेक्स्ट XAML के माध्यम से सेट किया गया है। अगर मैं वीएस या ब्लेंड में यह UserControl खोलता हूं तो यह मुझे डमी कार्ड दिखाता है जिसे मैंने इसी व्यूमोडेल में परिभाषित किया है।

अब मेरे पास "CardSetControl" नामक एक और उपयोगकर्ता नियंत्रण है, जो कार्ड का संग्रह प्रदर्शित करना चाहिए। तो व्यूमोडेल में एक प्रकार की संपत्ति है ObservableCollection < कार्ड > जिसे "कार्ड" कहा जाता है।

यहाँ कोड है:

<ListBox x:Name="MyList" ItemsSource="{Binding CardSet.Cards}"> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
     <StackPanel> 

     <!-- WORKING, but not what i want --> 
     <TextBlock Text="{Binding ID}" /> // would display ID of Card 
     <Image Source="{Binding Image}" /> // would display Image of Card 

     <!-- NOT WORKING, but this is how i want it to work --> 
     <UserControls:CardControl DataContext="{Binding "Current listbox item as DataContext of CardControl???"}" /> 

     </StackPanel> 
    </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

MVVM और DataContext के बारे में लेख की टन पढ़ने के बाद/बाइंडिंग मैं अभी भी यह काम करने के लिए नहीं मिला। यह संपूर्ण पदानुक्रमित यूएसर कंट्रोल्स/डेटाकॉन्टेक्स चीजों ने सबसे अच्छा तरीका कैसे बनाया है?

उत्तर

13

ListBox नियंत्रण किसी अनुमानित ListBoxItem आइटम स्रोत में प्रत्येक आइटम के लिए बनाया जाता है। आइटम को डेटा कॉन्टेक्स्ट के रूप में सेट किया गया है और आपका आइटम टेम्पलेट टेम्पलेट के रूप में सेट है। चूंकि DataContext को विरासत में मिला है, इसलिए आपको इसे स्पष्ट रूप से सेट करने की आवश्यकता नहीं है क्योंकि यह पहले से ही आपके डेटा टेम्पलेट में कार्ड का उदाहरण है।

इस मामले के लिए, आपको डीसी को कार्डकंट्रोल पर सेट करने की आवश्यकता नहीं है क्योंकि यह आपके लिए सेट है।

<ListBox x:Name="MyList" ItemsSource="{Binding CardSet.Cards}"> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
     <StackPanel> 

     <!-- WORKING, but not what i want --> 
     <TextBlock Text="{Binding ID}" /> // would display ID of Card 
     <Image Source="{Binding Image}" /> // would display Image of Card 

     <!-- NOT WORKING, but this is how i want it to work --> 
     <UserControls:CardControl /> 

     </StackPanel> 
    </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

आपके लिए काम करना चाहिए।

14

आपके उदाहरण में, UserControl का डेटाकॉन्टेक्स्ट वर्तमान में चयनित कार्ड होगा। यह UserControl में बहता है और इसके बच्चे के नियंत्रण किसी भी अन्य UIElement को अपने मूल नियंत्रण के DataContext प्राप्त करता है।

यह काम करेगा:

<ListBox x:Name="MyList" ItemsSource="{Binding CardSet.Cards}"> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
     <UserControls:CardControl /> 
    </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

CardControl कहां है:

<UserControl x:Class="MySolution.CardControl" 
      OtherProperties="Not shown to keep this example small"> 
     <StackPanel> 
     <TextBlock Text="{Binding ID}" /> 
     <Image Source="{Binding Image}" /> 
     </StackPanel> 
</UserControl> 
+0

विल, मेरी क्षमा याचना मैं मूल रूप से ठीक उसी जवाब आप के रूप में दिया:

यहाँ लेख है।अगली बार जवाब देने से पहले मुझे पृष्ठ को रीफ्रेश करना चाहिए;) –

+0

इस तरह एक मॉडल (कार्ड) को उपयोगकर्ता नियंत्रण में डेटाकॉन्टेक्स्ट के रूप में पास किया जाता है। क्या होगा यदि मैं उस उपयोगकर्ता नियंत्रण को अपने दृश्य मॉडल का उपयोग करने के लिए रखना चाहता हूं? मुझे इस मॉडल को एक व्यू मॉडल में कैसे पास करना चाहिए और दृश्य मॉडल को नियंत्रण के दृश्य में बांधना चाहिए? –

+0

@ ओन्ड्रेज जेनेसेक: UserControls को अपने स्वयं के दृश्य मॉडल रखने के लिए डिज़ाइन नहीं किया जाना चाहिए। उनके पास अपनी सतह पर सार्वजनिक बाध्यकारी गुण होना चाहिए कि उपयोगकर्ता अपने स्वयं के दृश्य मॉडल से जुड़ जाएंगे। यह उत्तर ओपी के लिए सर्वोत्तम प्रथाओं की तुलना में अधिक आकार दिया गया है:/ – Will

1

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

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

आज मुझे डेटाकॉन्टेक्स्ट पदानुक्रम के बारे में एक दिलचस्प लेख मिला। ऐसा कहा जाता है कि ListBox के अंदर DataContext उसी डेटाकॉन्टेक्स्ट के समान नहीं है जिस पर ListBox है। मैंने इसे पहले नहीं देखा था, इसलिए मैंने सोचा कि मुझे डेटाकॉन्टेक्स्ट को किसी तरह से सेट करना है जैसा कि मैंने उल्लेख किया है सवाल। अब मैं सभी गुणों से बांध सकता हूं। http://blog.thekieners.com/2010/09/08/relativesource-binding-with-findancestor-mode-in-silverlight/