由于 ToolTip 不是 VisualTree 的一部分,所以这有点棘手。这里有一个很酷的解决方案,用于解决上下文菜单的同样问题。你可以用同样的方法来解决 ToolTip 的问题。
更新
遗憾的是,该链接已经失效,我再也找不到那篇文章了。
据我记得,该博客展示了如何绑定到另一个VisualTree的DataContext,这在从ToolTip、ContextMenu或Popup进行绑定时经常需要。
一个不错的方法是,在PlacementTarget的Tag属性中提供所需的实例(例如ViewModel)。以下示例演示了如何访问ViewModel的Command实例:
<Button Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=Self}}">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding PlacementTarget.Tag.DesiredCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu}}" .../>
<ContextMenu>
</Button.ContextMenu>
</Button>
我没有测试过,而且距上次尝试已经很久了,请在无法运行时留言告知。
更新2
由于此答案所写的原始链接已失效,我在archive.org上搜寻并找到了原博客文章。以下是完全引用该博客的内容:
因为 WPF 中的 ContextMenu 并不像您的页面/窗口/控件那样存在于视觉树中,数据绑定可能会有些棘手。我已经在网络上搜索了各种答案,最常见的答案似乎是“只需在代码后台中处理它”。 错误!我来到 XAML 的美妙世界,不想回到代码后台做事情。
这是我的一个例子,允许您绑定到作为窗口属性存在的字符串。
public partial class Window1 : Window
{
public Window1()
{
MyString = "Here is my string";
}
public string MyString
{
get;
set;
}
}
<Button Content="Test Button"
Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
<Button.ContextMenu>
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag,
RelativeSource={RelativeSource Self}}" >
<MenuItem Header="{Binding MyString}"/>
</ContextMenu>
</Button.ContextMenu>
</Button>
重要的部分是按钮的标签(虽然您也可以轻松设置按钮的DataContext)。这会存储对父窗口的引用。ContextMenu能够通过它的PlacementTarget属性访问此内容。然后,您可以将此上下文传递给菜单项。
我承认这不是世界上最优雅的解决方案。但是,它胜过在代码后面设置东西。如果有人有更好的方法,请告诉我。