上下文菜单绑定到父窗口的 Datacontext

Posted

技术标签:

【中文标题】上下文菜单绑定到父窗口的 Datacontext【英文标题】:Context Menu Binding to Parent Window's Datacontext 【发布时间】:2014-12-09 03:29:32 【问题描述】:

我有一个 TreeListControl 绑定到我的 VM 中的一个集合。我还想在 treelistcontrol 中定义上下文菜单,使其标题文本绑定到我的 VM 中的另一个字符串。在这种情况下如何设置数据上下文?我试过了

<Window.DataContext>
    <model:ViewModel></model:ViewModel>
</Window.DataContext>
<Grid>
<Button Grid.Row="1"  Command="Binding CellCheckedCommand"></Button>

    <TextBlock Text="Binding HeaderText" Grid.Row="2">
        <TextBlock.ContextMenu>
            <ContextMenu>
                <MenuItem DataContext="Binding RelativeSource=RelativeSource AncestorType=x:Type Window, Path=DataContext"  Header="Binding HeaderText"></MenuItem>
            </ContextMenu>
        </TextBlock.ContextMenu>
    </TextBlock>
</Grid>

但它不起作用。

这是视图模型

public DelegateCommand CellCheckedCommand  get; set; 

private String _HeaderText;

public String HeaderText 

    get
    
        return _HeaderText;
    
    set
    
        _HeaderText = value;
        NotifyPropertyChanged("HeaderText");
    


public void NotifyPropertyChanged(String name)
 
    if(PropertyChanged != null)
    
        PropertyChanged(this, new PropertyChangedEventArgs(name));
    


private void CellCheckedMethod()

    HeaderText = "Changed";

【问题讨论】:

您正在与两件事作斗争,上下文菜单 (cm) 的性质及其所在的父级。单独的 CM 可以绑定到其内部视觉树之外。但是一旦 CM 被放置在一个没有可视化树的对象上(就像树列表或数据网格上的某些项目),现在人们正在努力寻找页面的可视化树。您已经了解了绑定,但每个控件都有自己的特点。也许扩展树项的数据类以指向当前VM(?)。这样绑定就可以访问当前的虚拟机,而不必费劲。 最简洁的绑定文字可以在MSDN上找到:Data Binding Overview 【参考方案1】:

为您的窗口提供一个名称并显式绑定到它,例如

<window  x:Name="ReportsPage"/>

...

 <MenuItem DataContext="Binding ElementName=ReportsPage"/>

更新

由于上下文菜单实际上是在它自己的窗口中,绑定有点棘手。因此,最好的办法是将RelativeSource 向上移动到上下文的父级并从那里拉出标题文本:

    <Window.DataContext>
        <local:MainVM HeaderText="Jabberwocky" />
    </Window.DataContext>

    ...

<TextBlock Text="Binding HeaderText">
    <TextBlock.ContextMenu>
        <ContextMenu>

<MenuItem Header="Binding Path=Parent.DataContext.HeaderText, 
                    RelativeSource=RelativeSource Self" />

        </ContextMenu>
    </TextBlock.ContextMenu>

在这个上下文中哪个会产生这个

【讨论】:

@Helic 添加Path=DataContext. @Helic 明白了。我将尝试一个示例并删除我的帖子,直到我可以让它工作为止。 @Helic 我未能完全限定与DataContext 的绑定。查看我的更新。 非常感谢您提供不同的解决方案。最后一个解决方案的设计时间是什么意思?另外,我用 ContextItem 的 Header 尝试了它们,它们都不起作用,但它们确实适用于 TextBlock ContextMenu 不支持datacontext,使用了thomaslevesque.com/2011/03/21/…这篇帖子中的解决方案,现在对我来说很好。【参考方案2】:

这绑定到Window:

DataContext="Binding RelativeSource=RelativeSource AncestorType=x:Type Window"

如果WindowViewModel上定义了命令AddItemCommand和属性AddItemText,则绑定到WindowDataContext

DataContext="Binding RelativeSource=RelativeSource AncestorType=x:Type Window, Path=DataContext"

【讨论】:

它不起作用,请看我下面的例子 跨度> @Helic 短版本的 ViewModel 会有所帮助 - 它具有 HeaderText、AddItemText、AddItemCommand 属性,因为仅从 .xamls 无法判断您想要实现的目标。 +1 相对示例。我将它添加到我的第二次更新中。 这不起作用,因为 ContextMenu 不在可视化树中,所以它永远找不到 x:Type Window

以上是关于上下文菜单绑定到父窗口的 Datacontext的主要内容,如果未能解决你的问题,请参考以下文章

将 UserControl ListBox ItemSsource 绑定到父 DataContext 时出错

WPF 绑定到父 DataContext

通过 MVVM 模式创建 UserControl - DataContext 并绑定到父级

在具有分层数据模板的树视图中绑定上下文菜单命令

DataContext和ItemSource

为啥在 XAML 中绑定 MainWindow 数据上下文与使用 this.datacontext=this 在代码隐藏中绑定的行为不同?