Search code examples
c#wpfdatagrid

DataGrid - key to run event handler on current item


The source to a small WPF program is shown below. It lists the directories under c:\windows in a DataGrid. The name is a link that can be clicked to open the directory in Explorer.

(This is just a proof of concept program to illustrate the question.)

Here's what it looks like:

enter image description here

Instead of only being able to click on the link to run the open action, I'd also like to set it up so that the user can press the o key when a row is highlighted in order to run the open action.

What's a good way to set this up? Note that the program is primarily specified in C# as opposed to XAML so if possible, please post your solution in C#. However, if necessary, XAML answers are welcome too!

MainWindow.xaml:

<Window x:Class="WpfFilesDataGrid.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"
        xmlns:local="clr-namespace:WpfFilesDataGrid"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>

    </Grid>
</Window>

MainWindow.xaml.cs:

using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;

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

            var data_grid = new DataGrid()
            {
                IsReadOnly = true,
                AutoGenerateColumns = false,
                ItemsSource = new DirectoryInfo(@"c:\windows").GetDirectories()
            };

            {
                var setter = new EventSetter()
                {
                    Event = Hyperlink.ClickEvent,
                    Handler = (RoutedEventHandler)((sender, e) => 
                    {
                        System.Diagnostics.Process.Start((data_grid.SelectedItem as DirectoryInfo).FullName);
                    })
                };

                var style = new Style();

                style.Setters.Add(setter);

                var col = new DataGridHyperlinkColumn()
                {
                    Header = "FullName",
                    Binding = new Binding("FullName"),
                    ElementStyle = style
                };

                data_grid.Columns.Add(col);
            }

            data_grid.Columns.Add(new DataGridTextColumn()
            {
                Header = "CreationTime",
                Binding = new Binding("CreationTime")
            });

            var dock_panel = new DockPanel();

            dock_panel.Children.Add(data_grid);

            Content = dock_panel;
        }
    }
}

Solution

  • You could for example handle the PreviewKeyDown event:

    data_grid.PreviewKeyDown += (s, e) =>
    {
        if(e.Key == Key.O && data_grid.SelectedItem is DirectoryInfo di)
            System.Diagnostics.Process.Start(di.FullName);
    };