Установите выбранный WPF DataGridCell на фокусированный и редактируемый по событию - PullRequest
0 голосов
/ 06 октября 2010

Woot, первый пост переполнения стека!Меня попросили поработать над настольным приложением, чтобы улучшить процесс инвентаризации для моей компании.Я баловался с WPF в школе и решил, что начну там.Изучив некоторые из них, я узнал о MVVM, составил проект и продвинулся вперед.Наконец, я застрял и ищу некоторую помощь, а также проверку работоспособности, чтобы убедиться, что я на правильном пути.

У меня есть DataGrid из одной колонки, связанный с наблюдаемой коллекцией.Пользователи приложения используют сканер для ввода значений. Одно потенциальное значение, которое я улавливаю в моем объекте модели «Ячейка», это значение «MoveNextColumn».Это вызывает пользовательское событие в моей модели, которое обрабатывается в модели представления.Предполагается, что обработчик имитирует пустые записи для всех оставшихся строк в этом столбце, устанавливает фокус на последнюю строку и ждет ввода, прежде чем двигаться дальше.Итак, вот что у меня получилось:

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 голосов
/ 08 октября 2010

Я добился определенного прогресса в этом.В приведенном выше коде вся сетка была оставлена ​​в недоступном для редактирования состоянии.Теперь это оставляет фокус на последней ячейке в моем столбце и позволяет мне отправлять данные с помощью сканирующего пистолета.

Кажется, это работает, но я все равно буду благодарен за отзыв о том, есть ли лучший способ.

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();                                         
        }                                   
    }

Обновлено 12.02.2010

Эй, есть важное обновление для этого.Первое, на что следует обратить внимание, это то, что в моем сценарии ввод текста осуществляется с помощью сканирующего пистолета, поэтому клавиши «Ввод» отправляются при каждом нажатии триггера.Он сбрасывает каждый символ, за которым сразу следует клавиша Enter.

WPF видит этот ввод и хочет установить фокус на DataGridCell непосредственно под ячейкой, в которую был получен ввод с помощью клавиши Enter.Приведенный выше код устанавливает фокус на последнюю ячейку, но затем событие клавиши Enter все еще срабатывает и обрабатывается DataGrid после запуска этого кода.В результате фокус возвращается к следующей ячейке, а не к последней, как я хочу.

Так что мне нужно либо выяснить, как использовать клавишу Enter для этого сканирования, либо мне нужносломать, как WPF обрабатывает клавиши ввода.Последняя строка там на самом деле выдает исключение.Мы пытаемся использовать класс Model (Class.cs) в качестве DataGridCell, и нет ничего, что могло бы справиться с этим приведением.Из-за этого метод Focus () пытается работать с нулевым объектом, и мы получаем исключение NullReferenceException.Это действительно смущало меня, потому что Visual Studio 2010 иногда ломался, чтобы предупредить меня об этом, но иногда это не сработало.Однако, если я запускаю исполняемый файл вне Visual Studio, он работает просто отлично.Это связано с тем, что необработанные, нефатальные исключения игнорируются и поведение клавиши Enter не работает как обычно.

Так что это работает, но довольно грубо.Мне нужно либо выяснить, как выполнить однократную обработку клавиши Enter и переопределить обработчик WPF по умолчанию, либо просто оставить все как есть и поморщиться.

...