【WPF】在ListBox中添加按钮右键Popup

ListBox中放了一个按钮,想要在右键操作时弹出一个包含多个控件的Popup,实现如下:

XAML:

 <ListBox x:Name="MyList"  ItemsSource="{Binding MyCollection}" ItemContainerStyle="{StaticResource LocalListBoxItemBaseStyle}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Button x:Name="BtnItem" Content="{Binding}" Click="BtnItem_Click" MouseRightButtonUp="BtnItem_MouseRightButtonUp" 
                            Tag="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}}"
                            Background="LightGray" Foreground="White" BorderThickness="0" FontSize="12" FontFamily="{StaticResource SYBold}" 
                            Style="{StaticResource ButtonDefault.Small}" Height="25" Width="25" HorizontalAlignment="Center" Margin="15,0,0,0"/>
                    <Popup x:Name="PopupItem" Placement="Right" AllowsTransparency="True" StaysOpen="False" PlacementTarget="{Binding ElementName=BtnItem}" >
                        <Border Background="White" BorderBrush="LightGray" BorderThickness="1" CornerRadius="6" Width="420">
                            <DockPanel Margin="4">
                                <Label Content=" 右键弹窗"/>
                                <Button  Content="点击"  Click="BtnYou_Click"/>
                            </DockPanel>
                        </Border>
                    </Popup>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.Template>
            <ControlTemplate TargetType="{x:Type ListBox}">
                <ScrollViewer HorizontalScrollBarVisibility="Disabled" IsDeferredScrollingEnabled="False" VerticalScrollBarVisibility="Auto" PanningMode="Both" CanContentScroll="False" PreviewMouseWheel="ScrollViewer_PreviewMouseWheel">
                    <VirtualizingStackPanel Orientation="Vertical" IsItemsHost="True" ScrollViewer.CanContentScroll="True">
                    </VirtualizingStackPanel>
                </ScrollViewer>
            </ControlTemplate>
        </ListBox.Template>
    </ListBox>

Code:

private void BtnItem_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    try
    {
        // 1. 获取被点击的按钮
        Button btn = sender as Button;
        if (btn == null) return;

        // 2. 标记事件已处理,防止触发其他右键逻辑(如 ListBox 的选中)
        e.Handled = true;

        // 3. 找到该按钮所在 DataTemplate 中的 Popup
        Grid parentGrid = btn.Parent as Grid;
        if (parentGrid != null)
        {
            // 查找名为 "PopupItem" 的控件
            Popup popup = parentGrid.FindName("PopupItem") as Popup;

            if (popup != null)
            {
                // 4. 设置 Popup 的放置目标为当前按钮,这样它会出现在按钮旁边
                popup.PlacementTarget = btn;
                popup.Placement = System.Windows.Controls.Primitives.PlacementMode.Right;

                // 5. 打开 Popup
                popup.IsOpen = true;
            }
        }

        return;
    }
    catch (Exception)
    {

    }
}

总结

要在 ListBox 的 DataTemplate 中实现‌右键点击按钮弹出 Popup‌,核心难点在于:
‌定位‌:Popup 需要出现在鼠标右键点击的位置或按钮附近。
---xaml和代码双重PlacementTarget设置
‌触发‌:需要捕获 MouseRightButtonDown 或 MouseRightButtonUp 事件。
--使用up事件,Down会松开右键popup关闭。e.Handled = true
‌数据上下文‌:Popup 内部需要访问当前 ListBoxItem 的数据。
--使用Grid+Tag解决

posted @ 2026-05-27 09:58  nap117  阅读(13)  评论(0)    收藏  举报