如何在WPF中右键单击按钮上下文菜单?

时间:2017-04-21 16:23:20

标签: c# wpf xaml

我正在开发一个WPF错误记录应用程序,当用户输入新的连接字符串时,会创建一个连接按钮,并在侧栏上显示为堆叠列表。

我想在这些连接按钮上进行右键单击事件,以显示查看,编辑,删除的按钮上下文菜单。

我的 MainWindow.xaml 补充工具栏网格是这样的,

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition Width="318*" />

        </Grid.ColumnDefinitions>
        <ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Disabled">
            <StackPanel Name="listConnections" Grid.Column="0" Background="#4682b4" Margin="0,0,0,-0.2" >
            </StackPanel>
        </ScrollViewer>

        </TabControl>
    </Grid> 

我正在调用 MainWindow.xaml.cs 中的Stackpanel listConnections

public MainWindow()
{
    InitializeComponent();

    GetUserData();
    //Button to create new connection
    listConnections.Children.Add(new NewConnectionButton(this));
    this.Closed += new EventHandler(MainWindow_Close);
}

Right-Click event WPF 我尝试按照此链接创建右键单击事件,但它不适合我。有人可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

您应该在按钮的资源中放置一个上下文菜单,例如

<NewConnectionButton.Resources>
    <ContextMenu x:Key="connectionButtonContext"  StaysOpen="true">
        <MenuItem Header="Add" Click="InternalAddButton_Click"/>
        <MenuItem Header="Delete" Click="InternalDeleteButton_Click"/>
        <MenuItem Header="Edit" Click="InternalEditButton_Click"/>
    </ContextMenu>
</NewConnectionButton.Resources>

此代码应位于NewConnectionButton UserControl内。在UserControl C#代码中,接受这些事件并公开它们 (InternalAddButton_ClickInternalDeleteButton_ClickInternalEditButton_Click)使用Button的人。然后,在你的MainWindow中向他们招揽。

答案 1 :(得分:1)

我在这里做的是:

  • 单独创建上下文菜单并将其分配给每个&#34;连接&#34; UI上的对象
  • 处理MenuItem.Click点击每个菜单项的事件
  • 解决列表中单击的项目并分别处理

MVVM和所有这些肯定都很好,但这种直截了当的方法至少是开始的好地方:

<Window x:Class="WpfApplication7.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <!-- Having CommandParameter is crucial here -->
        <ContextMenu x:Key="contextMenu">
            <MenuItem Header="View"
                      Click="View_OnClick"
                      CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Parent}"/>
            <MenuItem Header="Edit"
                      Click="Edit_OnClick"
                      CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Parent}" />
            <MenuItem Header="Delete"
                      Click="Delete_OnClick"
                      CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Parent}"/>
        </ContextMenu>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition Width="318*" />
        </Grid.ColumnDefinitions>
        <ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Disabled">
            <StackPanel Name="listConnections" Grid.Column="0" Background="#4682b4" Margin="0,0,0,-0.2" >
                <Button Click="BtnAdd_OnClick">New Connection</Button>
            </StackPanel>
        </ScrollViewer>
    </Grid>
</Window>

代码隐藏:

using System;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication7
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private static Label FindClickedItem(object sender)
        {
            var mi = sender as MenuItem;
            if (mi == null)
            {
                return null;
            }

            var cm = mi.CommandParameter as ContextMenu;
            if (cm == null)
            {
                return null;
            }

            return cm.PlacementTarget as Label;
        }

        private void BtnAdd_OnClick(object sender, RoutedEventArgs e)
        {
            listConnections.Children.Add(new Label
            {
                Content = "New Connection",
                ContextMenu = (ContextMenu)Resources["contextMenu"]
            });
        }

        private void View_OnClick(object sender, RoutedEventArgs e)
        {
            var clickedItem = FindClickedItem(sender);
            if (clickedItem != null)
            {
                MessageBox.Show(" Viewing: " + clickedItem.Content);
            }
        }

        private void Edit_OnClick(object sender, RoutedEventArgs e)
        {
            var clickedItem = FindClickedItem(sender);
            if (clickedItem != null)
            {
                string newName = "Connection edited on " + DateTime.Now.ToLongTimeString();
                string oldName = Convert.ToString(clickedItem.Content);
                clickedItem.Content = newName;
                MessageBox.Show(string.Format("Changed name from '{0}' to '{1}'", oldName, newName));
            }
        }

        private void Delete_OnClick(object sender, RoutedEventArgs e)
        {
            var clickedItem = FindClickedItem(sender);
            if (clickedItem != null)
            {
                string oldName = Convert.ToString(clickedItem.Content);
                listConnections.Children.Remove(clickedItem);
                MessageBox.Show(string.Format("Removed '{0}'", oldName));
            }
        }
    }
}

这就是它的样子:

about to click edit

after clicking on edit

希望这有帮助