【问题标题】:Context Menu Binding to Parent Window's Datacontext上下文菜单绑定到父窗口的 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

标签: wpf c#-4.0 binding datacontext


【解决方案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}"

【讨论】:

  • 它不起作用,请看我下面的例子 跨度>
  • +1 相对示例。我将它添加到我的第二次更新中。
  • 这不起作用,因为 ContextMenu 不在可视化树中,所以它永远找不到 x:Type Window
猜你喜欢
  • 1970-01-01
  • 2011-04-22
  • 2016-03-08
  • 1970-01-01
  • 2012-11-05
  • 2013-07-26
  • 2013-02-02
  • 2020-02-22
相关资源
最近更新 更多