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 传递给 TagListBoxItem,然后您需要参考从 ContextMenu 通过它的 PlacementTarget 到它。都是因为 ContextMenu 使用了 Popupcreates 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>