3

コマンドを複合コレクションのメニュー項目にバインドする際に問題があります。のMenuItem一部はContextMenuで定義されていUserControl.Resourcesます。

問題は、New ラベルのバインドが機能していないことです。MenuItem を複合コレクションの外に配置すると、機能します。何か案は?

<UserControl.Resources>
    <ContextMenu x:Key="DataGridRowContextMenu">
        <MenuItem Header=" Set label"/>
            <MenuItem.ItemsSource>
                    <CompositeCollection>
                            <CollectionContainer Collection="{Binding Source={StaticResource labelsSelectSource}}" />
                    <MenuItem Header=" New label..." 
                          Command="{Binding DataContext.NewLabel,
                                RelativeSource={RelativeSource Mode=FindAncestor,
                                AncestorType={x:Type UserControl}}}"/>

                        </CompositeCollection>
                 </MenuItem.ItemsSource>
            </MenuItem>
<UserControl.Resources/>
4

3 に答える 3

1

これは、含まれている親ContextMenuと同じではないために発生し、データバインディングの問題が発生します。は同じビジュアルツリーにないvisual treeため、、()などのバインディングは機能しません。ContextMenuElementNameRelativeSouceFindAncestor

あなたはこれを回避することができます

  1. UserControlのコードビハインド:

    NameScope.SetNameScope(DataGridRowContextMenu, NameScope.GetNameScope(this)); 
    
  2. PlacementTargetこのようなプロパティを使用して-

    <ContextMenu 
        x:Key="DataGridRowContextMenu">   
        DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">
        .
        .  
        .
        <MenuItem 
            Header=" New label..."     
            Command="{Binding DataContext.NewLabel}"/> 
    

または、他のソリューションを使用してください-

ContextMenuのMenuItemからのElementNameバインディング

WPF:ContextMenuのDataContext

于 2012-07-25T10:10:17.230 に答える
1

私は長い間、このクレイジーな ContextMenu とその MenuItems と格闘し続けています。しかし、「Data」という名前の依存プロパティを持つカスタム動作「BindingProxyBehaviour」を作成するための解決策を見つけました。このプロパティは、たとえば DataContext (MVVM パターンを使用する場合は ViewModel など) などのオブジェクトを保持します。

public class BindingProxyDataBehavior : Freezable
{
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxyDataBehavior), new UIPropertyMetadata(null));

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxyDataBehavior();
    }

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }
}

このように xaml ファイルに BindingProxy をリソースとして追加するだけです。

<UserControl.Resources>
    <ResourceDictionary>
        <behaviors:BindingProxyDataBehavior x:Key="BindingProxyViewModel" Data="{Binding}"/>
        <behaviors:BindingProxyDataBehavior x:Key="BindingProxyViewModelDynamicDataList" Data="{Binding DynamicDataListObject}"/>
    </ResourceDictionary>
</UserControl.Resources>

私の場合、CompositeCollection を使用して、静的および動的な MenuItem を混同しています。したがって、キー「BindingProxyViewModelDynamicDataList」を持つ 2 番目のリソース。

これで、ContextMenu がどこにあるかに関係なく、データに簡単にアクセスできるようになりました。xaml ツリーでの私の ContexMenu の位置は、UserControl->Grid->DataGrid->DataGridTemplateColumn->CellTemplate->DataTemplate->TextBox.Template->Grid->TextBlock->controls:IconButton(ボタンから派生した単純な customButton コントロール) であり、ここではIconButton 内にあります。

<controls:IconButton.ContextMenu>
<ContextMenu x:Name="AnyContextMenuName">
    <ContextMenu.Resources>
        <HierarchicalDataTemplate DataType="{x:Type DynamicDataListItemType}">
            <TextBlock Text="{Binding DynamicDataListItemProperty}"/>
        </HierarchicalDataTemplate>
    </ContextMenu.Resources>
    <ContextMenu.ItemsSource>
        <CompositeCollection>
            <CollectionContainer Collection="{Binding Source={StaticResource BindingProxyViewModelDynamicDataList}, Path=Data}"/>
            <Separator/>
            <MenuItem Header="Your static header" Command="{Binding Source={StaticResource BindingProxyViewModel}, Path=Data.ViewModelCommandForYourStaticMenuItem}"/>
        </CompositeCollection>
    </ContextMenu.ItemsSource>
    <ContextMenu.ItemContainerStyle>
        <Style>
            <Setter Property="MenuItem.Foreground" Value="{DynamicResource DefaultForegroundBrush}"/>
            <Setter Property="MenuItem.Command" Value="{Binding Source={StaticResource BindingProxyViewModel}, Path=Data.ViewModelCommandForDynamicMenuItems}"/>
            <Setter Property="MenuItem.CommandParameter" Value="{Binding}"/>
        </Style>
    </ContextMenu.ItemContainerStyle>
</ContextMenu>
</controls:IconButton.ContextMenu>

この短い投稿で誰かを助けることができれば幸いです。

于 2015-08-20T07:45:34.113 に答える
0

プロパティを使用CommandTargetするか、datacontext の staticRessource を次のように作成します

<MenuItem Header=" New label..." 
          Command="{Binding Path=NewLabel,Source={StaticResource viewModel}}"/>
于 2013-01-08T16:57:37.553 に答える