列标题和行标题上下文菜单

时间:2012-01-10 14:33:57

标签: c# wpf command contextmenu wpfdatagrid

我正在使用WPF数据网格。我正在为行标题和列标题提供上下文菜单。代码如下所述:

MainWindow.xaml

<Window x:Class="WpfApplication10.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cmd="clr-namespace:WpfApplication10"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.Resources>
        <Style TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu>
                        <MenuItem Header="Insert Column Before" Command="cmd:ContextMenuCustomCommands.InsertColumnBeforeCommand" />
                        <MenuItem Header="Insert Column After" Command="cmd:ContextMenuCustomCommands.InsertColumnAfterCommand"/>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="{x:Type DataGridRowHeader}">
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu>
                        <MenuItem Header="Delete" Command="Delete"/>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
    </Grid.Resources>
    <Grid.CommandBindings>
        <CommandBinding Command="cmd:ContextMenuCustomCommands.InsertColumnBeforeCommand" CanExecute="InserColumnBefore_CanExecute" Executed="InserColumnBefore_Executed"/>
        <CommandBinding Command="cmd:ContextMenuCustomCommands.InsertColumnAfterCommand" CanExecute="InsertColumnAfter_CanExecute" Executed="InsertColumnAfter_Executed"/>
    </Grid.CommandBindings>
    <DataGrid x:Name="grdEmployee" ItemsSource="{Binding}" AutoGeneratingColumn="grdEmployee_AutoGeneratingColumn" LoadingRow="grdEmployee_LoadingRow" SelectionUnit="CellOrRowHeader">

    </DataGrid>
</Grid>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using System.Data.SqlClient;

namespace WpfApplication10
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private SqlConnection empCon = null;
        private SqlCommand empCmd = null;
        private DataSet empDS = null;
        private SqlDataAdapter empAdap = null;
        private string query = "SELECT * FROM Employees";
        public MainWindow()
        {
            InitializeComponent();

            this.grdEmployee.ItemsSource = this.GetEmployeeData().DefaultView;
        }

        private DataTable GetEmployeeData()
        {
            try
            {
                empCon = new SqlConnection(Application.Current.Properties["connectionStr"].ToString());
                empCmd = new SqlCommand(query, empCon);
                empAdap = new SqlDataAdapter(empCmd);
                empDS = new DataSet();
                empAdap.Fill(empDS);
            }
            catch (SqlException sqlEx)
            {
            }
            finally
            {
                if (empCon != null)
                    empCon.Dispose();

                if (empCmd != null)
                    empCmd.Dispose();
            }

            if (empDS != null)
            {
                for (int count = 1; count <= empDS.Tables[0].Columns.Count; count++)
                {
                    empDS.Tables[0].Columns[count - 1].ColumnName = Utility.ConvertNumber(count).ToString();
                }
                return empDS.Tables[0];
            }
            else
            {
                return null;
            }
        }

        private void grdEmployee_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {

        }

        private void grdEmployee_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            e.Row.Header = (e.Row.GetIndex() + 1).ToString();
        }

        private void InserColumnBefore_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void InserColumnBefore_Executed(object sender, ExecutedRoutedEventArgs e)
        {

        }

        private void InsertColumnAfter_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void InsertColumnAfter_Executed(object sender, ExecutedRoutedEventArgs e)
        {

        }
    }

    public class Utility
    {
        private static string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

        public static string ConvertNumber(int number)
        {
            string result;
            number -= 1;
            int rest = number % 26;
            int q = number / 26;
            if (q == 0)
            {
                result = chars[rest].ToString();
            }
            else
            {
                result = ConvertNumber(q) + chars[rest];
            }
            return result;
        }
    }

    public static class ContextMenuCustomCommands
    {
        public static readonly RoutedUICommand InsertColumnBeforeCommand = new RoutedUICommand("Insert Column Before", "Insert Column Before", typeof(MainWindow));
        public static readonly RoutedUICommand InsertColumnAfterCommand = new RoutedUICommand("Insert Column After", "Insert Column After", typeof(MainWindow));
    }
}

App.xaml.cs

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;

namespace WpfApplication10
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public App()
        {
            string connectionStr = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Northwind;Data Source=(local);";
            Application.Current.Properties["connectionStr"] = connectionStr;
        }
    }
}

我面临的问题是,列标题上的上下文菜单保持禁用状态,除非我访问数据网格。我无法弄清楚原因。

请帮帮我。如果您需要任何其他信息,请告诉我。

1 个答案:

答案 0 :(得分:0)

如上所述,问题似乎源于DataGrid在点击时没有聚焦的事实。

在加载的事件中调用gid.Focus();通过将焦点放在GridView上来解决问题。

至于检测单击的列,您可以通过类似于获取详细信息的单元格和行信息的事件处理程序来获取in this article