2010-12-06 11 views
21

コントロールにObservableCollectionタイプの添付プロパティがあります。コレクションにアイテムを追加または削除すると、UIは更新されません。しかし、コレクション内のコレクションを新しいものに置き換えると、ViewModelが更新されます。ObservableCollection依存関係プロパティは、コレクション内のアイテムが削除されても更新されません。

私がDependencyオブジェクト内で行う必要があることの例を、コレクション内の変更を処理できるように教えてもらえますか?依存関係オブジェクトの

一部を以下にリストされている:

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

A依存関係プロパティの値が変更されていないため、コレクション内の変更によって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

ありがとうございます。 SpecialDays_CollectionChanged内の依存関係オブジェクトの参照を取得することは可能ですか? – GoalMaker

+0

どの依存オブジェクトですか?あなたはRadCalendarを意味しますか?とにかく、私はそれが理にかなっているとは確信していません:いくつかのRadCalendarのインスタンスが同じコレクションにバインドされている場合はどうでしょうか? –

+0

私はあなたが何を意味するかを見ます。私はRadCalendarがコレクションから削除されても特別な日を強調表示しないようにしようとしていたので、新しいSpecialDaySelectorを作成し、CalendarコントロールのDayTemplateSelectorを設定することでこれを行うかもしれないと思った。 – 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

これは役に立ちます。はい、私は、CollectionChangedEventHandlerのDependencyObjectにアクセスする方法を探しています。これはうまくいくようです。私はこれが唯一の方法だと信じるのは難しいと思っています...私たちは間違ったことをしていますか?私はObservableCollection DPを持っています。アイテムが追加されると(collectionchangedイベントが発生します...)、メインコントロール(サブコントロールの追加など)に必要な作業が必要になります。そして、あなたの解決策は私がDependencyObjにアクセスするために見つけた唯一のものです。この投稿はあなたが別の方法を見つけたので、 – 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 
} 
関連する問題