如何禁用FlipView键盘按键而不禁用子控件

时间:2016-01-18 23:17:00

标签: c# wpf xaml mahapps.metro

故事,我在我的窗口内使用MahApps.Metro FlipView,FlipView里面包含一个GridView,这个工作完美,但我有一个问题,我不能用键盘箭头浏览GridView单元格, UpDown箭头正常工作,但不是LeftRight箭头,当我按下它时,flipview会更改页面。

我尝试像这样处理OnPreviewKeyPress,

private void FlipView_PreviewKeyDown(object sender, KeyEventArgs e)
{
    e.Handled = true;
}

但是GridView也没有收到按键。

1 个答案:

答案 0 :(得分:2)

您在试图处理PreviewKeyDown时走在正确的轨道上。诀窍是,您需要手动触发KeyDown的{​​{1}}事件。

这是一个适用于我的测试用例的实现:

DataGrid

假设:您只想禁止在(1)所选项目为private void UIElement_PreviewKeyDown(object sender, KeyEventArgs e) { var dataGrid = FlipView.SelectedItem as DataGrid; if (dataGrid == null) return; // the selected item is not a DataGrid if (!dataGrid.SelectedCells.Any()) return; // no selected cells to move between // create a new event args to send to the DataGrid var args = new KeyEventArgs( Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, e.Key); args.RoutedEvent = Keyboard.KeyDownEvent; // get the event dataGrid.RaiseEvent(args); // raise the event e.Handled = true; // prevent the FlipView from going forward/backward } 和(2){时向前/向后移动FlipView的能力{1}}有一个或多个选定的单元格。 (否则,您希望箭头键正常工作。)

以下是我的测试用例的完整代码:

MainWindow.xaml.cs:

DataGrid

MainWindow.xaml:

DataGrid

如果您希望箭头在选中最左侧或最右侧的单元格时起作用,请将using System.Collections.Generic; using System.Linq; using System.Windows.Controls; using System.Windows.Input; namespace Sandbox { public partial class MainWindow { public List<Item> Items { get; set; } public MainWindow() { InitializeComponent(); DataContext = this; Items = new List<Item> { new Item { Id = 1, Name = "First" }, new Item { Id = 2, Name = "Second" }, new Item { Id = 3, Name = "Third" }, new Item { Id = 4, Name = "Fourth" }, }; } private void UIElement_PreviewKeyDown(object sender, KeyEventArgs e) { var dataGrid = FlipView.SelectedItem as DataGrid; if (dataGrid == null) return; if (!dataGrid.SelectedCells.Any()) return; var args = new KeyEventArgs( Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, e.Key); args.RoutedEvent = Keyboard.KeyDownEvent; dataGrid.RaiseEvent(args); e.Handled = true; } public class Item { public int Id { get; set; } public string Name { get; set; } } } } 事件处理程序替换为:

<Window x:Class="Sandbox.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:Sandbox"
        xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
        mc:Ignorable="d"
        Title="MainWindow"
        Width="525"
        Height="350">
    <controls:FlipView x:Name="FlipView"
                       Margin="0, 0, 10, 0"
                       Height="200"
                       IsBannerEnabled="True"
                       PreviewKeyDown="UIElement_PreviewKeyDown">
        <controls:FlipView.Items>
            <DataGrid ItemsSource="{Binding Items}"
                      AutoGenerateColumns="True" />
            <Rectangle Margin="0, 0, 10, 0"
                       Width="50"
                       Height="50"
                       Fill="Red" />
            <Rectangle Margin="0, 0, 10, 0"
                       Width="50"
                       Height="50"
                       Fill="Blue" />
        </controls:FlipView.Items>
    </controls:FlipView>
</Window>

此外,PreviewKeyDown的XAML应设置以下属性,以确保一次只能选择一个单元格:

private void UIElement_PreviewKeyDown(object sender, KeyEventArgs e)
{
    var dataGrid = FlipView.SelectedItem as DataGrid;
    if (dataGrid == null) return;
    if (!dataGrid.SelectedCells.Any()) return;

    // get the column index of the selected cell
    var columnIndex = dataGrid.SelectedCells.First().Column.DisplayIndex;

    // exit if the selected cell is left/right and the arrow is left/right
    if (columnIndex == 0 && e.Key == Key.Left ||
        columnIndex == dataGrid.Columns.Count - 1 && e.Key == Key.Right) return;

    var args = new KeyEventArgs(
        Keyboard.PrimaryDevice,
        Keyboard.PrimaryDevice.ActiveSource,
        0,
        e.Key);
    args.RoutedEvent = Keyboard.KeyDownEvent;
    dataGrid.RaiseEvent(args);
    e.Handled = true;
}