6

如何在 ContextMenu 中获取 UserControl 的原始 DataContext。

下面的代码,可以看到DataTemplate中有一个Button,绑定正确。但是,当尝试绑定上下文菜单的数据源时,我收到以下错误:

System.Windows.Data 错误:4:找不到与引用“RelativeSource FindAncestor,AncestorType='System.Windows.Controls.TreeView',AncestorLevel='1''的绑定源。绑定表达式:路径=数据上下文;数据项=空;目标元素是'ContextMenu'(名称='');目标属性是“DataContext”(类型“对象”)

我需要做什么才能让 ContextMenu 绑定到 ViewModel?

==================================================== ==============================

ViewModel 在代码隐藏中分配给视图的数据上下文:

看法:

<TreeView ItemsSource="{Binding Clients}"
          cmd:TreeViewSelect.Command="{Binding SelectionChangedCommand}"
          cmd:TreeViewSelect.CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=SelectedItem}">
    <TreeView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}">
                    <TextBlock.ContextMenu>
                        <ContextMenu DataContext="{Binding DataContext, 
                            RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeView}}}">
                            <MenuItem Header="{Binding TestString}" />
                        </ContextMenu>
                    </TextBlock.ContextMenu>
                </TextBlock>

                <Button  DataContext="{Binding DataContext, 
                            RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeView}}}"
                         Content="{Binding TestString}" Command="{Binding EditSelectedClientCommand}" />
             </StackPanel>
        </DataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

视图模型:

public class ClientListViewModel : ViewModelBase
{
    public String TestString { 
        get {
            return "TESTING";  
        }
    }

    private ClientList _clients = null;
    private readonly IClientService _clientService = null;
    private readonly IEventAggregator _eventAggregator = null;
    private Client _selectedClient = null;
    private ICommand _selectionChangedCommand = null;
    private ICommand _editSelectedClientCommand = null;
    ....
}
4

1 回答 1

10

ContextMenus不会出现在导致 RelativeSource 绑定失败的可视化树中,但您仍然可以获得DataContext一种或另一种方式。你可以试试这个,例如:

<TextBlock Text="{Binding Name}"
           Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=TreeView}}">
    <TextBlock.ContextMenu>
        <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
            <MenuItem Header="{Binding TestString}" />
            <!-- ... --->

PlacementTargetTextBlock,并且DataContext是通过Tag. 只有一种方法可以做到这一点(至少我希望它有效),我还看到一些图书馆以不同的方式弥合了这一差距,但我不记得它们的起源......

于 2011-07-26T01:04:05.717 回答