WPF "static" 列表中的绑定
WPF "static" binding in a List
我在列表中绑定时遇到问题。
我有一个对象列表。此列表绑定到一个列表框。对于列表中的每个对象,我都可以打开一个上下文菜单:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="First" IsEnabled="{Binding FirstEnabled}"/>
<MenuItem Header="Second" IsEnabled="{Binding SecondEnable}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
在这样的代码中,我在列表中的对象具有两个要绑定的布尔值。现在我想将这两个布尔值绑定到对象上。我想将它 "static" 绑定到我的 DataContext。这不是这样工作的,我不知道如何实现它。
我在谷歌上搜索了很多,但没有找到任何有用的信息...
感谢您的帮助!
您可以使用 ElementName 语法引用每个数据上下文:
<ListBox x:Name="myListBox">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="First" IsEnabled="{Binding Path=DataContext.FirstEnabled, ElementName=myListBox}"/>
<MenuItem Header="Second" IsEnabled="{Binding Path=DataContext.SecondEnable, ElementName=myListBox}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
使用此语法,您可以使用 ListBox 的 DataContext,而不是 ListItem。
因为,ContextMenu
应用于 ListBoxItem
,它将具有其 DataContext
值,而 ListBoxItem
将是其 PlacementTarget
。因此,如果您想绑定到 ListBox.DataContext
的 属性,您需要将当前的 ListBox.DataContext
传递给 Tag
到 ListBoxItem
,然后您需要参考从 ContextMenu
通过它的 PlacementTarget
到它。都是因为 ContextMenu
使用了 Popup
而 creates its own visual tree 如此简单的 RelativeSource
/ElementName
绑定将不起作用
<Style TargetType="ListBoxItem">
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBox}}, Path=DataContext}"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="First" IsEnabled="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.FirstEnabled}"/>
<MenuItem Header="Second" IsEnabled="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.SecondEnable}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
我在列表中绑定时遇到问题。
我有一个对象列表。此列表绑定到一个列表框。对于列表中的每个对象,我都可以打开一个上下文菜单:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="First" IsEnabled="{Binding FirstEnabled}"/>
<MenuItem Header="Second" IsEnabled="{Binding SecondEnable}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
在这样的代码中,我在列表中的对象具有两个要绑定的布尔值。现在我想将这两个布尔值绑定到对象上。我想将它 "static" 绑定到我的 DataContext。这不是这样工作的,我不知道如何实现它。
我在谷歌上搜索了很多,但没有找到任何有用的信息...
感谢您的帮助!
您可以使用 ElementName 语法引用每个数据上下文:
<ListBox x:Name="myListBox">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="First" IsEnabled="{Binding Path=DataContext.FirstEnabled, ElementName=myListBox}"/>
<MenuItem Header="Second" IsEnabled="{Binding Path=DataContext.SecondEnable, ElementName=myListBox}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
使用此语法,您可以使用 ListBox 的 DataContext,而不是 ListItem。
因为,ContextMenu
应用于 ListBoxItem
,它将具有其 DataContext
值,而 ListBoxItem
将是其 PlacementTarget
。因此,如果您想绑定到 ListBox.DataContext
的 属性,您需要将当前的 ListBox.DataContext
传递给 Tag
到 ListBoxItem
,然后您需要参考从 ContextMenu
通过它的 PlacementTarget
到它。都是因为 ContextMenu
使用了 Popup
而 creates its own visual tree 如此简单的 RelativeSource
/ElementName
绑定将不起作用
<Style TargetType="ListBoxItem">
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBox}}, Path=DataContext}"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="First" IsEnabled="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.FirstEnabled}"/>
<MenuItem Header="Second" IsEnabled="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.SecondEnable}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>