简体   繁体   中英

Determining which listboxitem is clicked on in a listbox when executing a context menu

I am trying to use context menu in a listbox to run some come code.that require data from which item it originated.the click event context menu item shows msg but i found that it doent not access the originating listview item .

<Canvas x:Name="LeftCanvas"  Grid.Column="0" Grid.Row="1" Margin="5,0,0,0">
    <StackPanel>
        <TextBlock Text="Unseated Guests" Background="Blue" Foreground="White" FontFamily="Verdana" FontSize="11" FontWeight="Bold" Height="17" Width="150" HorizontalAlignment="Left" TextAlignment="Center"  Padding="0,4,5,2"></TextBlock>
        <ListBox x:Name="UnseatedPersons" ItemsSource="{Binding}" Height="218"  Width="150" BorderBrush="Blue" BorderThickness="2" HorizontalAlignment="Left" Padding="3,2,2,2" src:FloorPlanClass.DragEnabled="true" MouseEnter="UnseatedPersons_MouseEnter"
             MouseLeave="SourceListBox_MouseLeave">
            <ListBox.ItemTemplate>
                <DataTemplate>
                        <DockPanel>
                            <DockPanel.ContextMenu>
                                <ContextMenu>
                                    <MenuItem Header="Archive Info" Click="bt_click" />
                                    <MenuItem Header="Guest Info" />
                                </ContextMenu>
                            </DockPanel.ContextMenu>
                            <Image Name="imgPerson" Source="{Binding ImagePath}" />
                            <TextBlock Name="txtPersonName" Text="{Binding PersonName}" Padding="2,4,0,0" />
                        </DockPanel>
                    </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>            
</Canvas>

C#:

void bt_click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("my message");
}

Use the sender by casting them to MenuItem . Like:

void bt_click(object sender, RoutedEventArgs e) 
{ 
    MenuItem originalItem = (MenuItem)sender;
    MessageBox.Show(string.Format("clicked from \"{0}\"", originalItem.Name)); 
}
  1. The sender in the click event will be the MenuItem you clicked.
  2. Its parent will be the ContextMenu
  3. The PlacementTarget of the ContextMenu will be the DockPanel .
  4. The DockPanel will have the ListBoxItem as an ancestor in the Visual Tree

So to get the ListBoxItem in the click event you can use something similar to this

private void bt_click(object sender, RoutedEventArgs e)
{
    MenuItem clickedMenuItem = sender as MenuItem;
    ContextMenu contextMenu = clickedMenuItem.Parent as ContextMenu;
    DockPanel dockPanel = contextMenu.PlacementTarget as DockPanel;
    ListBoxItem listBoxItem = GetVisualParent<ListBoxItem>(dockPanel);
    MessageBox.Show(listBoxItem.ToString());

    // Update. To display the content of the ListBoxItem
    MessageBox.Show(listBoxItem.Content.ToString());
}

public static T GetVisualParent<T>(object childObject) where T : Visual
{
    DependencyObject child = childObject as DependencyObject;
    // iteratively traverse the visual tree
    while ((child != null) && !(child is T))
    {
        child = VisualTreeHelper.GetParent(child);
    }
    return child as T;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM