【问题标题】:Access ViewModel / DataConext inside ContextMenu在 ContextMenu 中访问 ViewModel / DataConext
【发布时间】:2011-10-13 00:46:17
【问题描述】:

如何在 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;
    ....
}

【问题讨论】:

    标签: c# wpf data-binding mvvm prism-4


    【解决方案1】:

    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}" />
                <!-- ... --->
    

    PlacementTarget 是 TextBlock,DataContext 通过Tag 建立隧道。只是一种方法(至少我希望它有效),我还看到一些库以不同的方式弥合了这一差距,但我不记得它们的起源......

    【讨论】:

    • 这很棒!谢谢!您提到了可能弥补这一差距的其他库,Prism 会是其中之一吗?
    • 很高兴它有帮助 :) 我不知道 Prism 是否支持它,我只是再次环顾四周,this 将是我之前遇到的那些库之一,但我不知道如果它可以在这种情况下工作,因为我认为我从未真正使用过它。然而,我不久前尝试了另一个名为 DataContextSpy 的东西,但它对我没有多大用处,也许我应用错了......
    • 我缺少的是 Tag 属性!谢谢!
    猜你喜欢
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 2014-09-26
    • 1970-01-01
    相关资源
    最近更新 更多