2012-02-03 15 views
3

標準グリッドから派生したカスタムコントロールを作成しようとしています。 カスタムコントロールのDependencyPropertyとしてObservableCollectionを追加しました。しかし、そのget/setは決して達成されません。 ObservableCollectionと正しく動作するDependencyPropertyを作成する際のガイドラインはいくつかありますか?DependencyProperty getter/setterが呼び出されていない

public class MyGrid : Grid 
{ 
    public ObservableCollection<string> Items 
    { 
     get 
     { 
      return (ObservableCollection<string>)GetValue(ItemsProperty); 
     } 
     set 
     { 
      SetValue(ItemsProperty, value); 
     } 
    } 

public static DependencyProperty ItemsProperty = 
       DependencyProperty.Register("Items", typeof(ObservableCollection<string>), 
     typeof(MyGrid), new UIPropertyMetadata(null, OnItemsChanged)); 

} 
+0

observablecollectionはあなたのコントロールではなく、あなたのビューモデルにあるはずです。 – thumbmunkeys

+0

これは既に私のビューモデルに入っています。しかし、どのようにグリッドに渡すのですか?グリッドはコレクションを扱う方法も知ってはいけませんか? – phm

+0

[ItemsControl.ItemsSource](http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemssource.aspx)のように、依存関係プロパティをIEnumerableとして定義できます。誰かが何が間違っているのかを見ることができるように、コードを投稿してください。 – Clemens

答えて

8

私はItems依存関係プロパティの型としてのObservableCollectionを使用しないことをお勧め。

ここでObservableCollectionを持つ理由は、プロパティ値が割り当てられているときにUserControlにCollectionChangedハンドラをアタッチできるようにするためです。しかし、ObservableCollectionはあまりにも具体的です。

ItemsControl.ItemsSourceなどの)WPFのアプローチでは、非常に基本的なインターフェイスタイプ(IEnumerableなど)を定義し、プロパティに値が割り当てられている場合は、値コレクションが特定のより特定のインターフェイスを実装しているかどうかを確認します。これは少なくともINotifyCollectionChangedになりますが、コレクションにはICollectionViewINotifyPropertyChangedも実装されている可能性があります。これらのインターフェースはすべて必須ではなく、依存関係プロパティーを複合体ItemCollectionまでの単純な配列から始めて、あらゆる種類のコレクションにバインドすることができます。

あなたOnItemsChangedプロパティ変更コールバックは次のようになります。

private static void OnItemsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
{ 
    MyGrid grid = obj as MyGrid; 

    if (grid != null) 
    { 
     var oldCollectionChanged = e.OldValue as INotifyCollectionChanged; 
     var newCollectionChanged = e.NewValue as INotifyCollectionChanged; 

     if (oldCollectionChanged != null) 
     { 
      oldCollectionChanged.CollectionChanged -= grid.OnItemsCollectionChanged; 
     } 

     if (newCollectionChanged != null) 
     { 
      newCollectionChanged.CollectionChanged += grid.OnItemsCollectionChanged; 

      // in addition to adding a CollectionChanged handler 
      // any already existing collection elements should be processed here 
     } 
    } 
} 

private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    // handle collection changes here 
} 
+0

恐ろしく、男! :-) – zoidbeck

4

WPF結合メカニズムは標準のCLRプロパティをバイパスし、依存関係プロパティのアクセサ(GetValueSetValue)に直接移動することがあります。

ロジックをCLRプロパティの内部に配置するのではなく、変更したハンドラの内部に配置する必要があります。それは実際に呼び出している

<local:MyGrid> 
    <local:MyGrid.Items> 
     <sys:String>First Item</sys:String> 
     <sys:String>Second Item</sys:String> 
    </local:MyGrid.Items> 
</local:MyGrid> 

Items、その後は各元素のAddを呼び出すことで取得する:あなたは次のように、XAMLからコレクションのプロパティを使用するときため

はまた ObservableCollection<string>が設定されることはありません。

関連する問題