【问题标题】:ListBox Map J and K Keys to Up/Down Arrow KeysListBox 将 J 和 K 键映射到上/下箭头键
【发布时间】:2013-07-07 17:04:10
【问题描述】:

我有一个 ListBox,我只想将 J 和 K 键绑定到向上和向下箭头键所绑定的任何命令。 WPF 列表框中的向上和向下箭头键通常将所选项目更改为上一个/下一个项目。我认为这样的事情应该可行:

  <ListBox.InputBindings>
    <KeyBinding Key="J" Command="ScrollBar.LineDownCommand" />
    <KeyBinding Key="K" Command="ScrollBar.LineUpCommand" />
  </ListBox.InputBindings>

我可能在这里太简单了。

【问题讨论】:

    标签: wpf


    【解决方案1】:

    您可以在命令中使用DependencyClass。定义ListBox.InputBindings中的命令:

    XAML

    <ListBox Name="SampleListBox" Width="200" Height="200" KeyboardNavigation.DirectionalNavigation="Cycle" SelectedIndex="{Binding MySelectedIndex}">
        <ListBox.InputBindings>
            <KeyBinding Command="{Binding NextCommand}" Gesture="CTRL+J" />
            <KeyBinding Command="{Binding PrevCommand}" Gesture="CTRL+K" />
        </ListBox.InputBindings>
    
        <ListBoxItem>Sample 1</ListBoxItem>
        <ListBoxItem>Sample 2</ListBoxItem>
        <ListBoxItem>Sample 3</ListBoxItem>
        <ListBoxItem>Sample 4</ListBoxItem>
    </ListBox>
    

    Code behind

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
    
            // Set your data
            this.DataContext = new MainWindowViewModel();
    
            // Set focus
            SampleListBox.Focus();
        }
    }
    
    /// <summary>
    /// Class with commands
    /// </summary>
    public class MainWindowViewModel : DependencyObject
    {
        public ICommand NextCommand 
        {
            get; 
            set; 
        }
    
        public ICommand PrevCommand
        { 
            get;
            set;
        }
    
        public int MySelectedIndex
        {
            get
            {
                return (int)GetValue(MySelectedIndexProperty);
            }
    
            set
            {
                SetValue(MySelectedIndexProperty, value);
            }
        }
    
        public static readonly DependencyProperty MySelectedIndexProperty =
            DependencyProperty.Register("MySelectedIndex", typeof(int), typeof(MainWindowViewModel), new UIPropertyMetadata(0));
    
        public MainWindowViewModel()
        {
            MySelectedIndex = 0;
    
            NextCommand = new SimpleCommand(SetNext);
            PrevCommand = new SimpleCommand(SetPrev);
        }
    
        private void SetNext()
        {
            MySelectedIndex += 1;
        }
    
        private void SetPrev()
        {
            if (MySelectedIndex > 0)
            {
                MySelectedIndex -= 1;
            }
        }
    }
    
    public class SimpleCommand : ICommand
    {
        private Action _action;
    
        public SimpleCommand(Action p_action)
        {
            _action = p_action;
        }
    
        public bool CanExecute(object parameter)
        {
            return true;
        }
    
        public event EventHandler CanExecuteChanged;
    
        public void Execute(object parameter)
        {
            if (_action != null)
            {
                _action();
            }
        }
    }
    

    类中包含两个ICommand'sNextCommandPrevCommand。还有一个 DependencyProperty MySelectedIndex,其中包含项目的当前索引。在SimpleCommand 中总是返回true

    这只是一个例子,仍然需要检查Items ListBox的总数。或者不要增加SelectedIndex,而是使用ScrollViewer 逻辑。

    Extension

    ScrollViewer 为例:

    要滚动浏览ListBox 中的项目,您必须首先有权访问它。下面是对应的函数:

    public static DependencyObject GetScrollViewer(DependencyObject Object)
    {
        if (Object is ScrollViewer)
        {
            return Object;
        }
    
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(Object); i++)
        {
            var child = VisualTreeHelper.GetChild(Object, i);
            var result = GetScrollViewer(child);
    
            if (result == null)
            {
                continue;
            }
            else
            {
                return result;
            }
        }
    
        return null;
    }
    

    简单的功能滚动:

    private void OnScrollDown(object sender, RoutedEventArgs e)
    {
        if (MyListBox.Items.Count > 0) 
        {
            // Get ScrollViewer from ListBox
            ScrollViewer scrollViewer = GetScrollViewer(MyListBox) as ScrollViewer;
    
            if (scrollViewer != null)
            {
               // Increment offset - scrolling Down, sub - scrolling Up
               scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + ScrollListBoxOffset);
            }
        }
    }
    

    【讨论】:

    • 努力+1。 ListBox 已经具有滚动/选择行为,我只希望它连接到向上/向下箭头键。我原以为会有一种方法可以解决这种行为并将其连接到 J/K 键。不得不自己实现行为只是为了选择不同的键似乎有点蹩脚(不是你,WPF)。在这个和愚蠢的焦点问题之间,我准备放弃 WPF。
    猜你喜欢
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2011-06-14
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多