从工具提示或contextMenu结合的亲属之旅
-
01-10-2019 - |
题
我在这里做错了什么?
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button>
<Button.ToolTip>
<TextBlock Text="{Binding Path=Title, RelativeSource={RelativeSource AncestorType=Window}}" />
这只是一个简化的示例,无论如何都无效:)实际上,我需要从窗口dataContext范围的另一个属性中获取一个值。
帮我。
解决方案
这很棘手,因为工具提示不是VisualTree的一部分。 这里 您会看到ContextMenus同样问题的很酷的解决方案。您可以使用工具提示的方式。
更新
可悲的是,链接消失了,我还没有找到引用的文章。
据我所知,引用的博客已经显示了如何绑定到另一个VisualTree的数据台面,这通常是从工具提示,contextMenu或弹出窗口绑定时需要的。
做到这一点的好方法是在位置图的标签范围内提供所需的实例(例如ViewModel)。以下示例为访问ViewModel的命令命令而做到这一点:
<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>
重要的部分是按钮上的标签(尽管您可以轻松地设置按钮的数据台面)。这将存储对父窗口的引用。 ContextMenu能够通过其位置Target属性访问它。然后,您可以通过菜单项传递此上下文。
我承认这不是世界上最优雅的解决方案。但是,它击败了背后的代码中设置内容。如果有人有更好的方法来做到这一点,我很想听听。
其他提示
per以下:
PlacementTarget是拥有ContextMenu(Ex:DataGrid)的控件。无需“标签”属性。
ISENABLED绑定到DataGrid的“ myproperty”值。
我对此进行了测试,它起作用。绑定有类似的问题。
<ContextMenu
DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}"
IsEnabled="{Binding myProperty}"
>
因为 ContextMenu
不在视觉树中,绑定将行不通。一个简单的解决方案是使用代理模式,您可以创建一个从 DependencyObject
并有一个 DependencyProperty
那将保持一个 DataContext
你的 Window
, ,那么您可以在XAML中拥有代理的资源,最后绑定您的 MenuItem
通过代理对象命令到您所需的命令。
样本代理:
Public class ProxyClass : DependencyObject
{
Public object Data {get; set;}
public static readonly DependencyProperty DataProperty = DependencyProperty.Register("DataProperty", typeof(object), typeof(ProxyClass), new FrameworkPropertyMetadata(null));
}
如何在XAML中使用:
<Window DataContext="{Binding MyViewModel}">
...
<Window.Resources>
<ProxyClass Data={Binding} x:Key="BindingProxy"/>
</Window.Resources>
...
<MenuItem Command="{Binding Source={StaticResource BindingProxy}, Path=Data.MyDesiredCommand"/>
...
</Window>
怎么了?
Data
财产的 ProxyClass
将绑定到 DataContext
的 Window
, ,然后它具有您的所有comamnds和您的属性 ViewModel
在 - 的里面 ProxyClass
资源。
这种方法的另一个好处是可移植性和重复多种视图和项目。
我认为应该这样做:
{Binding Path=Title, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"