2011-07-27 21 views
1

私は独自のコンテキストメニューを持つユーザーコントロールを持っていますが、そのメニューにアイテムを追加する必要があります。データコレクションの依存プロパティをユーザーコントロールのメニューにバインドする

私が取ったアプローチは、依存関係プロパティと呼ばれるContextMenuItemsを持っていることでした。

<CompositeCollection x:Key="MenuItemsCompositeCollection"> 
     <MenuItem Header="TEST" /> 
     <CollectionContainer Collection="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=ContextMenuItems, Converter={StaticResource TestConverter}}" /> 
     <MenuItem Header="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=ContextMenuItems}" /> 
    </CompositeCollection> 
:私は、ホストによって提供されたリストでコントロールから静的メニュー項目を組み合わせるためにCompositeCollectionを使用
Public Shared ReadOnly ContextMenuItemsProperty As DependencyProperty = DependencyProperty.Register("ContextMenuItems", GetType(ObservableCollection(Of MenuItem)), GetType(SmartDataControl), New FrameworkPropertyMetadata(New ObservableCollection(Of MenuItem))) 
Public Property ContextMenuItems As ObservableCollection(Of MenuItem) 
    Get 
     Return GetValue(ContextMenuItemsProperty) 
    End Get 

    Set(ByVal value As ObservableCollection(Of MenuItem)) 
     SetValue(ContextMenuItemsProperty, value) 
    End Set 
End Property 

私はそのリソースに結合したときに、私が見るものは次のとおりです。

  • TEST
  • (コレクション)

2番目のメニュー項目は、私はそれを得ることができることを証明するために、コレクションにバインドされています。私はメニュー項目に追加したテストコンバーターを持っていますが、コンバーターメソッドでブレークしますが、コンバーターをCollectionContainerに追加すると呼び出されません。

は最後に、私は、出力ウィンドウに次のエラーが表示されます。

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression:Path=ContextMenuItems; DataItem=null; target element is 'CollectionContainer' (HashCode=41005040); target property is 'Collection' (type 'IEnumerable')

答えて

2

比べて2つのオブジェクトが明らかに等しくないので、あなたの「証拠」が機能しないこと。必要な条件が満たされていない、つまり、NameScopeが存在しないため、コレクションコンテナ内にまたはElementNameバインディングを使用することはできません。コレクションコンテナは、ビジュアルツリーに表示されないabtractオブジェクトであるため、見つけられた。

あなたはユーザーコントロールへのアクセス権を持っている場合は、しかしCompositeCollectionUserControl.Resourcesで定義され、その後、StaticResourceを使用して参照する必要がある周期的なdependecyエラーを防ぐために、UserControlの名前にBinding.Sourcex:Referenceを使用することができます。

<UserControl Name="control"> 
    <UserControl.Resources> 
     <CompositeCollection x:Key="collection"> 
      <!-- ... --> 
      <CollectionContainer Collection="{Binding ContextMenuItems, Source={x:Reference control}, Converter=...}"/> 
     </CompositeCollection> 
    </UserControl.Resources> 
    <!-- ... --> 
     <MenuItem ItemsSource="{Binding Source={StaticResource collection}}"/> 
</UserControl> 
+0

これはかなり意味があります。私はバインディング式にタイプミスがなかったことを証明していたことを知っていましたが、あなたのエクスプロレーションはなぜ1つの場所で動作するのか、別の場所では動作しないのかを明らかにしました。 Binding.Sourceとx:Referenceをどのように使用するかを示すXAMLを投稿できますか(MSのドキュメントはあまり役に立ちません)。ありがとう。 – Darren

+0

@Darren:例を追加して、最初の段落の一部を書き直しました。問題は実際にオブジェクトからの継承ではなく(MenuItemのバインディングがまだ機能しているので)、むしろCollectionContainerがVisualTree。一般に、バインディングの多くの処理はかなり難読化されています。いくつかのケースでは、あなたは非常に魔法かもしれない[人工的な継承コンテキスト](http://blogs.msdn.com/b/nickkramer/archive/2006/08/18/705116.aspx)を持っています... –

+0

パーフェクト - ありがとうすべての詳細について – Darren

関連する問題