2010-12-06 19 views
21

मेरे पास नियंत्रण पर अवलोकन योग्य चयन प्रकार की एक संलग्न संपत्ति है। अगर मैं संग्रह से आइटम जोड़ता या हटाता हूं, तो यूई अपडेट नहीं होता है। हालांकि अगर मैं संग्रह को एक नए के साथ बदलता हूं तो ViewModel ui अद्यतन करता है।पर्यवेक्षण योग्यता निर्भरता संपत्ति अद्यतन नहीं होती है जब संग्रह में आइटम हटा दिया जाता है

क्या कोई मुझे निर्भर करता है कि मुझे निर्भरता ऑब्जेक्ट के भीतर क्या करना है ताकि यह संग्रह के भीतर परिवर्तनों को संभाल सके?

निर्भरता वस्तु का एक हिस्सा नीचे सूचीबद्ध है:

public class RadCalendarBehavior : DependencyObject 
{ 
private static void OnSpecialDaysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    var calendar = d as RadCalendar; 
    if (e.NewValue != null) 
    { 
    calendar.DayTemplateSelector = new SpecialDaySelector((ObservableCollection<DateTime>)e.NewValue, GetSpecialDayTemplate(d)); 
    } 
} 

public static ObservableCollection<DateTime> GetSpecialDays(DependencyObject obj) 
{ 
    return (ObservableCollection<DateTime>)obj.GetValue(SpecialDaysProperty); 
} 

public static void SetSpecialDays(DependencyObject obj, ObservableCollection<DateTime> value) 
{ 
    obj.SetValue(SpecialDaysProperty, value); 
} 

public static readonly DependencyProperty SpecialDaysProperty = 
    DependencyProperty.RegisterAttached("SpecialDays", typeof(ObservableCollection<DateTime>), typeof(RadCalendarBehavior), new UIPropertyMetadata(null, OnSpecialDaysChanged)); 
} 
} 

मैं समझता हूँ कि मुझे लगता है कि संग्रह बदल गया है रजिस्टर करने की आवश्यकता है, लेकिन मैं कैसे निर्भरता संपत्ति

उत्तर

33

एक के भीतर ऐसा करने के लिए अनिश्चित हूं संग्रह के भीतर परिवर्तन OnSpecialDaysChanged कॉलबैक ट्रिगर नहीं करेगा, क्योंकि निर्भरता संपत्ति का मूल्य नहीं बदला है। आप संग्रह के साथ परिवर्तन का पता लगाने के लिए प्रतिक्रिया करने की जरूरत है, तो आप मैन्युअल रूप से घटना CollectionChanged घटना को संभालने की जरूरत है:

private static void OnSpecialDaysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    var calendar = d as RadCalendar; 

    if (e.OldValue != null) 
    { 
    var coll = (INotifyCollectionChanged)e.OldValue; 
    // Unsubscribe from CollectionChanged on the old collection 
    coll.CollectionChanged -= SpecialDays_CollectionChanged; 
    } 

    if (e.NewValue != null) 
    { 
    var coll = (ObservableCollection<DateTime>)e.NewValue; 
    calendar.DayTemplateSelector = new SpecialDaySelector(coll, GetSpecialDayTemplate(d)); 
    // Subscribe to CollectionChanged on the new collection 
    coll.CollectionChanged += SpecialDays_CollectionChanged; 
    } 
} 

private static void SpecialDays_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    // handle CollectionChanged 
} 
+0

धन्यवाद। क्या विशेष Days_CollectionChanged के भीतर निर्भरता ऑब्जेक्ट का संदर्भ प्राप्त करना संभव है? – GoalMaker

+0

कौन सा निर्भरता वस्तु? आप RadCalendar का मतलब है? आसानी से नहीं ... वैसे भी, मुझे यकीन नहीं है कि यह समझ में आएगा: क्या होगा यदि RadCalendar के कई उदाहरण एक ही संग्रह से बंधे हैं? –

+0

मुझे लगता है कि आपका क्या मतलब है। मैं रैड कैलेंडर को किसी विशेष दिन को संग्रहित करने के लिए किसी विशेष दिन को हाइलाइट करने की कोशिश नहीं कर रहा था, इसलिए मैंने सोचा कि मैं इसे नया स्पेशलडे चयनकर्ता बनाकर और कैलेंडर नियंत्रण के डे टेम्पलेट चयनकर्ता को सेट करके कर सकता हूं। – GoalMaker

5

यह थॉमस द्वारा जवाब में जोड़ने के लिए बस है। मेरी कोड में मैं नीचे की तरह localy हैंडलर ऑब्जेक्ट बनाने के द्वारा DependencyObject के गुणों के साथ बातचीत करते हैं:

private static void OnSpecialDaysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    var action = new NotifyCollectionChangedEventHandler(
      (o, args) => 
       { 
        var calendar = d as RadCalendar; 

        if (calendar!= null) 
        { 
         // play with calendar's properties/methods 
        } 
       }); 

    if (e.OldValue != null) 
    { 
     var coll = (INotifyCollectionChanged)e.OldValue; 
     // Unsubscribe from CollectionChanged on the old collection 
     coll.CollectionChanged -= action; 
    } 

    if (e.NewValue != null) 
    { 
     var coll = (ObservableCollection<DateTime>)e.NewValue; 
     // Subscribe to CollectionChanged on the new collection 
     coll.CollectionChanged += action; 
    } 
} 

आशा इस किसी के लिए उपयोगी है।

+0

यह सहायक है हां, मैं संग्रहChangedEventHandler में निर्भरता ऑब्जेक्ट तक पहुंचने का एक तरीका ढूंढ रहा हूं, और ऐसा लगता है। मुझे विश्वास करना मुश्किल लगता है कि यह एकमात्र तरीका है ... क्या हम कुछ गलत कर रहे हैं? मेरे पास एक ऑब्जर्जेबल कोलेक्शन डीपी है, जब आइटम इसमें जोड़े जाते हैं (संग्रहित ईवेंट निकाल दिया जाता है ...), मुझे मुख्य नियंत्रण (जैसे उप-नियंत्रण जोड़ें) में सामान करना होगा। और आपका समाधान केवल एकमात्र है जिसे मैंने निर्भरता ओबीजे तक पहुंचने के लिए पाया है। चूंकि इस पोस्ट में आपको एक और तरीका मिला है? – Sam

2

आप एक संग्रह की तरह निर्भरता संपत्ति है, तो रखने के निम्न बातों का ध्यान:

यदि आपकी संपत्ति एक संदर्भ प्रकार है, निर्भरता संपत्ति मेटाडाटा में निर्दिष्ट डिफ़ॉल्ट मान उदाहरण के अनुसार डिफ़ॉल्ट मूल्य नहीं है, इसके बजाय यह एक डिफ़ॉल्ट मान है जो प्रकार के सभी उदाहरणों पर लागू होता है। [...]
इस समस्या को ठीक करने के लिए, आपको क्लास कन्स्ट्रक्टर कॉल के हिस्से के रूप में संग्रह निर्भरता संपत्ति मान को एक अद्वितीय उदाहरण पर रीसेट करना होगा।

(MSDN Collection-Type Dependency Properties देखें)

सैम सवाल (मैं तो बस एक ही समस्या में भाग) उत्तर देने के लिए:

अपने CollectionChanged-हैंडलर गैर स्थिर बनाने और सदस्यता समाप्त/पुनः सदस्यता ले instance- पर स्तर।

private static void OnSpecialDaysChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    var calendar = d as RadCalendar; 

    if (e.OldValue != null) 
    { 
    var coll = (INotifyCollectionChanged)e.OldValue; 
    // Unsubscribe from CollectionChanged on the old collection of the DP-instance (!) 
    coll.CollectionChanged -= d.SpecialDays_CollectionChanged; 
    } 

    if (e.NewValue != null) 
    { 
    var coll = (ObservableCollection<DateTime>)e.NewValue; 
    calendar.DayTemplateSelector = new SpecialDaySelector(coll, GetSpecialDayTemplate(d)); 
    // Subscribe to CollectionChanged on the new collection of the DP-instance (!) 
    coll.CollectionChanged += d.SpecialDays_CollectionChanged; 
    } 
} 

private void SpecialDays_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    // handle CollectionChanged on instance-level 
} 
संबंधित मुद्दे

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