1

这是 XAML:

                <ListBox ItemsSource="{Binding Documents}" BorderBrush="{x:Null}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{Binding Title}" FontSize="12" FontWeight="Bold" />
                            <TextBlock Text="{Binding ID}" FontSize="10" FontStyle="Italic" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>

                <ListBox.ContextMenu>
                    <ContextMenu ItemsSource="{Binding CategoryList}">
                        <ContextMenu.ItemTemplate>
                            <DataTemplate>
                                <MenuItem Command="{Binding AddDocumentToCategoryContextMenuCommand}" Header="{Binding Category.Name}" />
                            </DataTemplate>
                        </ContextMenu.ItemTemplate>
                    </ContextMenu>
                </ListBox.ContextMenu>

            </ListBox>

好的,所以 ListBox 的 ItemSource 绑定到 VM 中的 Documents 集合并正确呈现标题和 ID

上下文菜单的 ItemSource 绑定到 VM 中的 CategoryList 集合并正确呈现类别列表。

我遇到的问题是命令绑定:

Command="{Binding AddDocumentToCategoryContextMenuCommand}"

由于已经设置了 ContextMenu 的 ItemSource,它会尝试从 CategoryList 中获取 AddDocumentToCategoryContextMenuCommand。显然该命令不存在,它是VM的成员。

我不希望对 XAML 中的 VM 或模型有任何引用。一切都是使用 Unity 构建的,VM-View 在 App.xaml 中关联:

<Application.Resources>
    <DataTemplate DataType="{x:Type vms:FeedViewModel}">
        <views:FeedView/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type vms:DocumentsViewModel}">
        <views:DocumentsView/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type vms:ManagementViewModel}">
        <views:ManagementView/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type dev:DevelopmentViewModel}">
        <dev:DevelopmentView />
    </DataTemplate>
</Application.Resources>

如何从 ContextItem 中将数据绑定到 VM 的成员。

谢谢。

更新的编辑 #1 从这里开始

这是更新的 xaml(但仍然无法正常工作,但获得了一些见解):

<ListBox ItemsSource="{Binding Documents}" x:Name="Results" BorderBrush="{x:Null}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{Binding Title}" FontSize="12" FontWeight="Bold" />
                            <TextBlock Text="{Binding ID}" FontSize="10" FontStyle="Italic" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>

                <ListBox.ContextMenu>
                    <ContextMenu ItemsSource="{Binding CategoryList}">
                        <ContextMenu.ItemTemplate>
                            <DataTemplate>
                                <MenuItem Command="{Binding ElementName=Results, Path=DataContext.AddDocumentToCategoryContextMenuCommand}" Header="{Binding Category.Name}" />
                            </DataTemplate>
                        </ContextMenu.ItemTemplate>
                    </ContextMenu>
                </ListBox.ContextMenu>

            </ListBox>

我有这个示例适用于不使用 ContextMenu 的简单示例。看起来 ContextMenu(即使附加到 ListBox)不是用户控件可视树的一部分。绑定总是返回 null / not found。我认为 ContextMenu,因为它是一个浮动“窗口”,是在它自己的树中构造的,因此无法找到 ListBox 调用“结果”以访问 ListBox 的 DataContext。

对此有什么想法吗?有关如何处理的任何建议?

编辑#2 从这里开始

如果您想知道,请找出具有约束力的问题的答案:

此绑定有效:

Command="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AddDocumentToCategoryContextMenuCommand}

希望这可以帮助其他有同样问题的人。

最后一次更新以确保完整性。

为了让命令知道单击了哪个上下文菜单项,我不得不稍微更改 xaml(愚蠢的疏忽):

                <ListBox.ContextMenu>
                    <ContextMenu x:Name="Context" ItemsSource="{Binding CategoryList}">
                        <ContextMenu.ItemTemplate>
                            <DataTemplate>
                                <MenuItem Command="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AddDocumentToCategoryContextMenuCommand}"  
                                            CommandParameter="{Binding Category.ID}"
                                            Header="{Binding Category.Name}" />
                            </DataTemplate>
                        </ContextMenu.ItemTemplate>
                    </ContextMenu>
                </ListBox.ContextMenu>

再次,希望这对其他人有所帮助。

4

1 回答 1

2

使用绑定的 ElementName 属性来指定。你最终会得到这样的东西:

Command="{Binding ElementName=ViewModelObject 
                  Path=AddDocumentToCategoryContextMenuCommand}"
于 2011-03-09T18:40:01.240 回答