将选定的WPF DataGridCell设置为聚焦和可编辑的事件

时间:2010-10-06 16:49:25

标签: c# wpf datagrid focus

Woot,第一个Stack Overflow帖子!我被要求在桌面应用程序上工作,以改善我公司的库存流程。我在学校学习WPF,我想我会从那里开始。在研究了一些之后,我了解了MVVM,将设计融合在一起,并取得了进展。最后,我陷入困境,寻求一些帮助,并进行健全检查,看看我是否走在正确的道路上。

我将单列DataGrid绑定到可观察集合。该应用程序的用户使用扫描枪输入值。我在“Cell”模型对象中捕获的一个潜在值是“MoveNextColumn”值。这会在我的模型中引发一个在View Model中处理的自定义事件。处理程序应该模拟该列中所有剩余行的空白条目,将焦点设置在最后一行,并在继续之前等待输入。所以这就是我到目前为止所做的:

private void dummyCell_MoveToNextColumn(object sender, RoutedEventArgs e) {
        e.Handled = true;

        // Cell is the model object containing the parsing rules and raising events
        var lSender = sender as Cell;
        var gridItems = ViewGridReference.Items;
        var lastItem = gridItems[gridItems.Count - 1];

        if (lSender == lastItem) {
            // We are at the bottom of the column
            // Move the program on to the next column
            CurrentColumn++;
            OnPropertyChanged("ItemPositions");
        } else {
            // Simulate "empty position" input for this cell and all cells down the column
            // Cells are validating themselves as the simulation progresses
            foreach (Cell item in ViewGridReference.Items) {
                item.ActualItemCode = string.Empty;
            }

            // ViewGridReference is a reference to my DataGrid set from the view
            ViewGridReference.Focus();

            ViewGridReference.SelectedIndex = gridItems.Count - 1;
            ViewGridReference.CurrentCell = new DataGridCellInfo(lastItem, ViewGridReference.Columns[0]);
            ((DataGridCell)ViewGridReference.SelectedItem).Focus();             
        }                                   
    }

所有这些似乎都按预期工作:所有行都接收空白输入并进行验证(我在视图所绑定的单元格中使用颜色属性来表示条目的有效性。)

不幸的是,尽管焦点位于最后一行,但它不可编辑,用户无法提交另一个“MoveNextColumn”值,这将启动程序。这里的目标是最小化任何键盘交互。一切都应该用扫描枪和条形码完成。

有关如何在执行此代码后使所选单元格可编辑的任何想法? 任何“嘿,你的设计糟透了”反馈也会很酷。这对我来说是新的,我对建设性的批评持开放态度。

1 个答案:

答案 0 :(得分:0)

我在这方面取得了一些进展。整个网格在上面的代码中处于不可编辑的状态。现在,这会将焦点放在我的列中的最后一个单元格中,并允许我使用扫描枪提交输入。

这似乎有效,但我仍然感谢一些关于是否有更好的方法的反馈。

private void dummyCell_MoveToNextColumn(object sender, RoutedEventArgs e) {
        e.Handled = true;

        // Cell is the model object containing the parsing rules and raising events
        var lSender = sender as Cell;
        var gridItems = ViewGridReference.Items;
        var lastItem = gridItems[gridItems.Count - 1];

        if (lSender == lastItem) {
            // We are at the bottom of the column
            // Move the program on to the next column
            CurrentColumn++;
            OnPropertyChanged("ItemPositions");
        } else {
            // Simulate "empty position" input for this cell and all cells down the column
            // Cells are validating themselves as the simulation progresses

            foreach (Cell item in ViewGridReference.Items) {
                item.ActualItemCode = string.Empty;
            }

            ViewGridReference.SelectedIndex = gridItems.Count - 1;
            ViewGridReference.CurrentCell = new DataGridCellInfo(lastItem, ViewGridReference.Columns[0]);

            (ViewGridReference.ItemsSource as ListCollectionView).EditItem(ViewGridReference.SelectedItem);
            ((DataGridCell)ViewGridReference.SelectedItem).Focus();                                         
        }                                   
    }

已于2010年12月2日更新

嘿,有一个重要的更新。首先要注意的是在我的场景中使用扫描枪完成文本输入,因此每次触发时都会发送“Enter”键。它会一次性击落每个角色,然后按Enter键。

WPF看到此输入并希望将焦点设置到接收Enter键输入的单元格正下方的DataGridCell。上面的代码将焦点设置为最后一个单元格,但是Enter键事件仍然会触发,并在运行此代码后由DataGrid处理。效果是焦点重置回后续单元格,而不是我想要的最后一个单元格。

因此,我需要弄清楚如何只使用Enter键进行扫描,或者我需要打破WPF处理Enter键的方式。那里的最后一行实际上引发了异常。我们正在尝试使用Model类(Class.cs)作为DataGridCell,并且没有任何东西可以处理该转换。因此,Focus()方法尝试对null对象进行操作,并得到NullReferenceException。这真让我感到困惑,因为Visual Studio 2010有时会突破以提醒我这个,但有时却不会。但是,如果我在Visual Studio之外运行可执行文件,它可以正常工作。这是因为忽略了未处理的非致命异常,并且Enter键行为无法正常运行。

所以它有效,但是非常粗略。我要么想弄清楚如何一次性处理Enter键并覆盖默认的WPF处理程序,或者只是保持原样和鬼脸。