1

独自のコンテキストメニューを備えたユーザーコントロールがありますが、そのメニューに項目を追加する必要があります。

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

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

次に、CompositeCollectionを使用して、コントロールの静的メニュー項目をホストから提供されたリストと組み合わせました。

    <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>

そのリソースにバインドすると、次のように表示されます。

  • テスト
  • (コレクション)

2番目のメニュー項目は、コレクションにバインドされており、アクセスできることを証明しています。メニュー項目に追加したテストコンバーターがあり、コンバーターメソッドで壊れますが、コンバーターをCollectionContainerに追加しても呼び出されません。

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

System.Windows.Dataエラー:4:参照'RelativeSource FindAncestor、AncestorType ='System.Windows.Controls.UserControl'、AncestorLevel='1''でバインドするためのソースが見つかりません。BindingExpression:Path = ContextMenuItems; DataItem = null; ターゲット要素は'CollectionContainer'(HashCode = 41005040); ターゲットプロパティは「コレクション」(タイプ「IEnumerable」)です。

4

1 に答える 1

2

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

ただし、UserControlにアクセスできる場合は、UserControlの名前にBinding.Sourcex:Referenceを使用できます。周期的な依存関係エラーを防ぐために、CompositeCollectionをで定義してUserControl.Resourcesから、を使用して参照する必要がありますStaticResource

例えば

<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>
于 2011-07-27T12:36:04.843 に答える