WPF:如何将命令应用于嵌套列表框的上下文菜单

时间:2012-06-12 14:35:58

标签: wpf listbox

我正在使用PRISM开发一个wpf应用程序。这是我的第一个WPF应用程序,我发现自己处于无法前进的境地。

我的场景是这样的,我有一个我用ListBox绑定的组列表,你可以将它称为父ListBox,每个组对象都有一个与之关联的用户列表,我将该列表与另一个ListBox绑定在一起嵌套在父ListBox中。两个绑定工作正常,你可以在这里看到:

enter image description here

我面临两个问题。

1。我可以单独选择组和单个用户,但它们不同步,意味着如果我选择了一个用户,那么包含该用户的组就不会被选中。我尝试过IsSynchronizedWithCurrentItem =“True”,但这似乎不起作用。

如果有人能指出我正确的方向如何实现这一目标,或者在ListBox中使用ListBox还有其他方法,我将不胜感激。

2. 我有一个与父ListBox关联的上下文菜单,我能够成功地将命令与菜单绑定,但是我遇到了使用嵌套ListBox Context Menu绑定命令的麻烦,这是我的代码

<ListBox x:Name="lstOfGroups" 
             ItemsSource="{Binding CurrentContest.Groups}"
             SelectedItem="{Binding SelectedGroup}"
             ItemTemplate="{StaticResource GroupTemplate}"
             Style="{StaticResource ListBoxStyle1}"
             ItemContainerStyle="{StaticResource ListBoxItemStyle1}"
             Background="Transparent" SelectionMode="Single"
             IsSynchronizedWithCurrentItem="True"
             Height="400">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Orientation="Horizontal" Margin="5" Width="1200"/>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>

                <ListBox.ContextMenu>
                    <ContextMenu>
                        <MenuItem Header="Add Contestant" Command="{Binding AddGroupCommand}"/>
                        <MenuItem Header="Edit Contestant" Command="{Binding EditGroupCommand}"/>
                        <MenuItem Header="Delete Contestant" Command="{Binding DeleteGroupCommand}"/>
                    </ContextMenu>
                </ListBox.ContextMenu>
            </ListBox>

<DataTemplate x:Key="GroupTemplate" >
        <Border x:Name="spPubItemBorder" Margin="3" BorderBrush="Black" BorderThickness="1" CornerRadius="10" Background="Honeydew">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <StackPanel Orientation="Horizontal">
                    <TextBlock Name="tbGroupName" Grid.Column="0" Style="{StaticResource ItemTextBox}">
                    <TextBlock.Text>
                        <MultiBinding StringFormat="{}Group Name: {0}">
                            <Binding Path="Name" />
                        </MultiBinding>
                    </TextBlock.Text>
                    </TextBlock>
                    <TextBlock Name="tbGroupAmount" Grid.Column="1" Style="{StaticResource ItemTextBox}">
                    <TextBlock.Text>
                        <MultiBinding StringFormat="{}Group Amount: {0}">
                            <Binding Path="Amount" />
                        </MultiBinding>
                    </TextBlock.Text>
                    </TextBlock>
                </StackPanel>
                <!--<ItemsControl ItemsSource="{Binding ContestantList}"
                              AlternationCount="2" ItemTemplate="{StaticResource ContestantTemplate}">

                </ItemsControl>-->
                <ListBox x:Name="lstOfContestant" Grid.Row="1"
                     ItemsSource="{Binding ContestantList}"
                     SelectedItem="{Binding SelectedContestant, ElementName=lstOfGroups}"
                     ItemTemplate="{StaticResource ContestantTemplate}"
                     Style="{StaticResource ListBoxStyleForContestant}"
                     ItemContainerStyle="{StaticResource ListBoxItemStyleForContestant}"
                     Background="Transparent" SelectionMode="Single"
                     Height="Auto">
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel Orientation="Horizontal" Margin="5" Width="375"/>
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>

                    <ListBox.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Add Contestant" Command="{Binding Path=DataContext.AddContestantCommand,ElementName=contestantManager}"/>
                            <MenuItem Header="Edit Contestant" Command="{Binding Path=DataContext.EditContestantCommand,ElementName=contestantManager}"/>
                            <MenuItem Header="Delete Contestant" Command="{Binding Path=DataContext.DeleteContestantCommand,ElementName=contestantManager}"/>
                        </ContextMenu>
                    </ListBox.ContextMenu>
                </ListBox>

            </Grid>
        </Border>
    </DataTemplate>

我想知道是否有人可以在这里指出我正确的方向。

提前致谢。

1 个答案:

答案 0 :(得分:1)

对于#1,如果IsSelected

,则将ListBox组的IsKeyboardFocusWithin属性设置为true
<Style x:Key="GroupListBoxItemStyle" TargetType="ListBoxItem">
  <Style.Triggers>
    <Trigger Property="IsKeyboardFocusWithin" Value="True">
      <Setter Property="IsSelected" Value="True" />
    </Trigger>
  </Style.Triggers>
</Style>

当键盘焦点位于ListBoxItem

内的任何位置时,这会将群组的ListBoxItem设置为已选择

对于#2,听起来你收到了错误的项目,可能是因为你在绑定中使用ElementName,但是名字是在多个项目上设置的。尝试使用RelativeSource绑定查找ContextMenu本身,然后绑定到PlacementTarget.DataContext

<MenuItem Header="Add Contestant"
          Command="{Binding PlacementTarget.DataContext.AddContestantCommand, 
              RelativeSource={RelativeSource FindAncestor, 
              AncestorType={x:Type ContextMenu}}}" />