2009-09-19 13 views
19

मैं एक संलग्न संपत्ति है कि इस वाक्य रचना के साथ इस्तेमाल किया जा सकता बनाना चाहते हैं:संलग्न संपत्ति

public class ToolbarItem 
{ 
    /// <summary> 
    /// Identifies the DisplayFilter attached property. 
    /// </summary> 
    public static readonly DependencyProperty DisplayFilterProperty = 
    DependencyProperty.RegisterAttached(
    "DisplayFilter", 
    typeof(IList), 
    typeof(ToolbarItem) 
    ); 

    public static IList GetDisplayFilter(Control item) { 
    return (IList)item.GetValue(DisplayFilterProperty); 
    } 

    public static void SetDisplayFilter(Control item, IList value) { 
    item.SetValue(DisplayFilterProperty, value); 
    } 
} 

लेकिन यह है:

<Button> 
    <Image .../> 
    <ui:ToolbarItem.DisplayFilter> 
    <TabItem .../> 
    <TabItem .../> 
    <TabItem .../> 
    </ui:ToolbarItem.DisplayFilter> 
</Button> 

यह ऐसा करने में मेरी प्रयास है पर्स-टाइम पर अपवाद पैदा कर रहा है - सिस्टम। ऑर्ग्यूमेंट अपवाद: टैबइटेम संपत्ति 'DisplayFilter' के लिए मान्य मान नहीं है। तो मैं अपनी संलग्न संपत्ति को कैसे कॉन्फ़िगर कर सकता हूं ताकि मैं वांछित XAML वाक्यविन्यास का उपयोग कर सकूं?

उत्तर

33

याद रखें कि एक्सएएमएल मूल रूप से ऑब्जेक्ट सृजन का एक लघुरूप रूप है। तो संलग्न DisplayFilter संपत्ति के मूल्य के रूप में संग्रह/सूची बनाने के लिए आपको अन्य संग्रह टैग के अंदर उन TabItems को संलग्न करना होगा। यदि आप ऐसा नहीं करना चाहते हैं, जो समझ में आता है, तो संपत्ति को पहली बार संग्रहित करने के लिए आपको संग्रह को प्रारंभ करना होगा।

इसमें केवल एक समस्या है: गेटटर विधि XAML रीडर द्वारा अनुकूलन के रूप में छोड़ी गई है। आप RegisterAttached कॉल करने के लिए नाम तर्क के लिए एक अलग नाम का चयन करके इस व्यवहार को रोका जा सकता है:

DependencyProperty.RegisterAttached("DisplayFilterInternal", ...) 

फिर संपत्ति गेटर बुलाया जाएगा और आप null के लिए देख सकते हैं। आप this blog post में इसके बारे में अधिक पढ़ सकते हैं।

संपादित करें: ऐसा लगता है कि लिंक किए गए ब्लॉग पोस्ट की तरह यह स्पष्ट नहीं है। आप केवल स्ट्रिंग RegisterAttached के लिए पारित का नाम बदल नहीं स्थिर प्राप्त/सेट तरीकों का नाम:

public static readonly DependencyProperty DisplayFilterProperty = 
    DependencyProperty.RegisterAttached(
     "DisplayFilterInternal", 
     typeof(IList), 
     typeof(ToolbarItem)); 

public static TabItemCollection GetDisplayFilter(Control item) 
{ ... } 

public static void SetDisplayFilter(Control item, IList value) 
{ ... } 

आप GetDisplayFilter विधि में संग्रह को प्रारंभ करने के लिए है:

public static TabItemCollection GetDisplayFilter(Control item) 
{ 
    var collection = (IList)item.GetValue(DisplayFilterProperty); 
    if (collection == null) { 
     collection = new List<object>(); 
     item.SetValue(DisplayFilterProperty, collection); 
    } 
    return collection; 
} 

ऐसा लगता है कि आप उस संग्रह में केवल TabItem तत्व जोड़ते हैं। फिर आप संग्रह प्रकार-सुरक्षित बना सकते हैं, लेकिन IList<T> का उपयोग नहीं कर रहा है क्योंकि XAML पार्सर सामान्य विधि Add(T) का आह्वान नहीं कर सकता है। Collection<T> और List<T> गैर-जेनेरिक IList इंटरफ़ेस को भी लागू करते हैं और इस मामले में उपयोग किए जा सकते हैं। मैं इस मामले में एक नया संग्रह प्रकार बनाने के लिए सुझाव है कि आप भविष्य में संग्रह के लिए कुछ परिवर्तन करना चाहते हैं:

public class TabItemCollection : Collection<TabItem> 
{ 
} 

आप इस तरह स्पष्ट रूप से संग्रह करने के बारे में परवाह नहीं है, तो:

<ui:ToolbarItem.DisplayFilter> 
    <ui:TabItemCollection> 
     <TabItem/> 
    </ui:TabItemCollection> 
</ui:ToolbarItem.DisplayFilter> 

आप SetDisplayFilter विधि को हटा सकते हैं।

संक्षेप में:

public class TabItemCollection : Collection<TabItem> 
{ 
} 

public class ToolbarItem 
{ 
    public static readonly DependencyProperty DisplayFilterProperty = 
     DependencyProperty.RegisterAttached(
      "DisplayFilterInternal", // Shadow the name so the parser does not skip GetDisplayFilter 
      typeof(TabItemCollection), 
      typeof(ToolbarItem)); 

    public static TabItemCollection GetDisplayFilter(Control item) 
    { 
     var collection = (TabItemCollection)item.GetValue(DisplayFilterProperty); 
     if (collection == null) { 
      collection = new TabItemCollection(); 
      item.SetValue(DisplayFilterProperty, collection); 
     } 
     return collection; 
    } 

    // Optional, see above note 
    //public static void SetDisplayFilter(Control item, TabItemCollection value) 
    //{ 
    // item.SetValue(DisplayFilterProperty, value); 
    //} 
} 
+0

मेरी प्रतिक्रिया, HTH स्पष्ट! – gix

+0

फिर कुछ और गलत होना चाहिए क्योंकि पोस्ट किया गया कोड ठीक काम करता है। एक संक्षिप्त और पूर्ण उदाहरण के लिए http://nopaste.org/p/adqfm5EPi देखें। – gix

+0

ऐसा लगता है कि आप इस तरह संसाधनों का उपयोग नहीं कर सकते हैं। यदि आप संसाधनों या स्पष्ट संग्रह का उपयोग नहीं करते हैं तो यह काम करता है। – gix

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