3

I have a datagrid in my MVVM application which, because of the way the client wants the data displayed, needs use template columns. They want some typical data-entry functionality though (pressing enter performs data checking, commits the row if valid, focuses on the first textbox of the next row; pressing tab focuses the next textbox...). Also, data is often imported from an external source into the grid, usually thousands of records at a time.

Right now, I have a Loaded event hooked up to each textbox which I am using to set focus after new rows are added. My problem is that the grid goes haywire when I import a lot of rows. As the user scrolls, the Loaded events are fired, and the grid becomes basically unusable. I disabled virtualization to prevent this, and find my grid taking up a gig of RAM in certain configurations, which is unacceptable. I can't figure out a way to get this grid to work the way they require without using a huge amount of memory. It seems as if I just need to be able to focus a textbox within a newly added row, but since the data validation is performed in the viewmodel, I don't have access to the new row in codebehind, so I can't just call "newtextbox.focus()" or whatever. I'm getting pretty desperate here, any suggestions would be massively appreciated.

drowned
  • 530
  • 1
  • 12
  • 31
  • 1
    Focus is kind of a party pooper in WPF. Check this post by Josh Smith http://joshsmithonwpf.wordpress.com/2010/03/16/control-input-focus-from-viewmodel-objects/ , maybe there are hints for a solution. – Matthieu Aug 01 '11 at 20:34
  • What about a solution where you skip editing / validation in the grid and just use the grid for display. Then when a grid-row is say, double clicked you pop-up a grid-row-editor which works as the editing of rows in the grid. – hkon Aug 01 '11 at 20:59
  • That definitely isn't gonna fly... the client wants data entry directly within the grid. I tried. – drowned Aug 01 '11 at 21:07
  • @drowned, are you using bulk inserts into ObservableCollection which is bound to your data grid? – WPF-it Aug 02 '11 at 13:24
  • No I'm not. During data entry, I'm inserting one row at a time... during an import, I'm just assigning a new collection to the object bound to the grid. – drowned Aug 02 '11 at 13:50

1 Answers1

2

Put an event listener in the code behind that can call your newtextbox.focus() (and whatever else you want to do). In the validation in the view model, fire the event with args that indicate what you want your grid to do.

Edit: OK, new approach. Try trapping the keystrokes, and on enter or tab do the things you want it to do.

This would be in your xaml

<Grid  KeyUp="myDataGrid_KeyUp" >

This would go in your code-behind

    private void myDataGrid_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            // do your enter stuff here, manipulate the view model for validation, etc.
        }
        else if (e.Key == Key.Tab)
        {
            // do your tab stuff here (get selected row, determine cell focus, focus on next cell)
        }
    }
Brad Boyce
  • 1,248
  • 1
  • 17
  • 34
  • This sounds interesting, but, without using static events, how can I fire an event in the viewmodel which could be handled in the codebehind? – drowned Aug 02 '11 at 17:55
  • I ended up abandoning the MVVM approach for this screen and just going with this answer purely in codebehind. I simply don't have any more time to fight with this ridiculous architecture just to say it's "MVVM". Trapping the key events works perfectly, thanks. – drowned Sep 16 '11 at 16:10
  • Great! Glad it worked for you. I also have mostly MVVM, but sometimes you just have to do what works so you can get on to the next problem. – Brad Boyce Sep 19 '11 at 13:54