2009-07-23 20 views
6
<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1" 
    Title="Window1"> 
    <Grid> 
     <local:ElementType x:Name="FirstElementName"> 
      <local:ElementType x:Name="SecondElementName" Grid.Column="1" Grid.Row="1" /> 
     </local:ElementType> 
    </Grid> 
</Window> 

और यह अन्य फ़ाइलों में है ...मैं कस्टम एक्सएएमएल तत्वों को कैसे बना सकता हूं?

<Grid x:Name="InternalElementName" x:Class="WpfApplication1.ElementType" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1"> 
</Grid> 

और ...

public partial class ElementType : System.Windows.Controls.Grid { } 

सब कुछ ठीक काम करता है, दूसरा तत्व को छोड़कर।
मुझे त्रुटि मिलती है:
तत्व 'ElementType' पर नाम विशेषता मान 'SecondElementName' सेट नहीं कर सकता। 'एलिमेंट टाइप' तत्व 'एलिमेंट टाइप' के दायरे में है, जिसका नाम पहले से ही एक नाम था जब इसे किसी अन्य दायरे में परिभाषित किया गया था।

कस्टम ग्रिड ठीक से परिभाषित किए गए हैं। कोड संकलन होगा और चलाने अगर मैं संपत्ति बाहर ले ---

x:Name="SecondElementName" 

--- Window1.xaml

में इस त्रुटि उत्पन्न कर रहा है? मैं इसके आसपास कैसे हो सकता हूं? मुझे इन कस्टम ग्रिड में से किसी एक के अंदर घोंसला करने की ज़रूरत है, और मुझे उन दोनों पर नामों की आवश्यकता है ताकि मैं उन्हें डेटा अलग करने के लिए बाध्य कर सकूं।

अग्रिम धन्यवाद।

उत्तर

5

नेस्टेड मार्कअप ऑब्जेक्ट्स के साथ क्या करना है, यह जानने के लिए, एक्सएएमएल पार्सर अन्य चीजों के साथ, यह देखें कि .NET क्लास एक डिफ़ॉल्ट "सामग्री" संपत्ति को ऐसे बच्चों के लिए कंटेनर के रूप में उपयोग करने के लिए परिभाषित करता है या नहीं। यह "ContentPropertyAttribute" के साथ किया जाता है।

आपके मामले में, के बाद से मुझे लगता है कि आप नेस्टेड वस्तुओं ग्रिड के अंदर जाने के लिए चाहते हैं, और के बाद से एक ग्रिड के बच्चों के "बच्चे" संपत्ति संग्रह में जाना है, तो आप सिर्फ निम्नलिखित कार्य करने होंगे:

[ContentProperty("Children")] 
public partial class ElementType : Grid 
{ 
    // your code here... 
} 

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

नामकरण समस्या के लिए, ऐसा लगता है कि केवल लापरवाही नियंत्रण बच्चों को एक त्वरित क्षेत्र में नामित कर सकते हैं। तो मूल रूप से, आप ElementType.xaml के अंदर बच्चों का नाम दे सकते हैं, लेकिन अन्य मार्कअप में बच्चों को नामित नहीं किया गया है जहां आप ElementType को तुरंत चालू करते हैं। मुझे लगता है कि यह तार्किक पेड़ या कुछ अनुकूलित करने के तरीके के कारण है। दूसरी तरफ एक लापरवाही नियंत्रण केवल कोड के साथ नियंत्रण है। तो यदि आप अपनी कक्षा को ग्रिड के एक पुराने पुराने खाली सबक्लास में बदलते हैं, तो यह काम करता है:

public class ElementType : Grid 
{ 
} 

यय! कम कोड!

+0

यह भी दिलचस्प है, लेकिन यह अभी भी मुझे माता-पिता और बच्चे ElementType ऑब्जेक्ट्स को अलग-अलग नाम देने की अनुमति नहीं देता है। क्या किसी को पता है कि मैं उन्हें एक-दूसरे से अलग तरीके से कैसे नामित कर सकता हूं? – Giffyguy

+0

ओह हाँ, क्षमा करें ... मैं अपना उत्तर ऊपर पूरा कर दूंगा। – Ludovic

1

आप अन्य भीतर एक चाहते हैं, तो आपको पहले की सामग्री संपत्ति में आंतरिक एक रखना चाहता हूँ चाहते हैं:

<local:ElementType x:Name="FirstElementName"> 
    <local:ElementType.Content> 
     <local:ElementType x:Name="SecondElementName" Grid.Column="1" Grid.Row="1" /> 
    </local:ElementType.Content> 
</local:ElementType> 

इसके अलावा, मुझे यकीन है कि तुम क्या यहाँ पूरा करने के लिए कोशिश कर रहे हैं नहीं कर रहा हूँ , लेकिन मुझे डर है।

+0

ऐसा लगता है कि इस शीर्षक होना करने के लिए सही दिशा है। आपके अंतिम प्रेषण के बारे में: एचए! मैंने जानबूझकर कुछ भी छोड़ दिया जो विनिर्देशों को दूर करेगा --- मेरा विश्वास करो, आप जानना नहीं चाहते हैं। आपके समाधान के बारे में, मुझे एक त्रुटि मिल रही है: "अनुलग्नक संपत्ति 'सामग्री' प्रकार 'ElementType' में नहीं मिली थी" मैंने अपनी जगह "ग्रिड.कंटेंट" की कोशिश की है और मुझे लगभग एक ही त्रुटि मिलती है। कोई और विचार? – Giffyguy

+0

मेरा मतलब "बच्चे" था, सामग्री नहीं। ऐसा लगता है कि आपको यह मिला है, यद्यपि। –

0

यदि आप UserControl को बदलना नहीं चाहते हैं, तो एक संलग्न व्यवहार का उपयोग करें। तो आपको बस इसकी आवश्यकता है, जहां एक्सएएमएल-संकलन असफल रहा! प्रत्येक उपयोगकर्ता नियंत्रण के लिए केवल 1 व्यवहार जो परेशानी करता है।

XAML में

:

<preview:PreviewControl> 
    <i:Interaction.Behaviors> 
     <behaviors:UserControlNameBehavior Name="ICanSetNames"/> 
    </i:Interaction.Behaviors> 
</preview:PreviewControl> 

सी # में:

public class UserControlNameBehavior : Behavior<UserControl> 
    { 
     public string Name { get; set; } 

     protected override void OnAttached() 
     { 
      this.AssociatedObject.Loaded += OnLoaded; 
      base.OnAttached(); 
     } 

     private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) 
     { 
      this.AssociatedObject.Name = this.Name; 
     } 
    } 
+0

व्यवहार वर्ग क्या है? मैं क्या हूं –

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