Access DataGrid from ViewModel

Sep 9, 2014 at 1:14 PM
Edited Sep 9, 2014 at 1:23 PM
Is there a way using EventTrigger or some other method in SimpleMVVM to access a DataGrid in the ViewModel. I have a requirement that we display a grid but instead of having the blank row at the bottom of the grid we have an 'Add' button to add the new row.

What I would like to do is to place the focus on the newly added row when the 'Add' button is clicked. I have found that I can call something like this:
PropertiesDataGrid.ScrollIntoView(PropertiesDataGrid.SelectedItem, null);
but not sure how to get a reference to 'PropertiesDataGrid' in the view model.

Here is the code for the view:
<DataGrid Name="PropertiesDataGrid" 
                          ItemsSource="{Binding PropertiesDataView, UpdateSourceTrigger=PropertyChanged}"
                          AutoGenerateColumns="False"
                          CanUserAddRows="False"
                          MaxHeight="250">
                          
                      
                        <DataGridTextColumn Header="ID"
                                            Width="50" 
                                            Binding="{Binding ID}" 
                                            ElementStyle="{StaticResource CenterTextCellStyle}" 
                                            IsReadOnly="True" />

                        <DataGridTextColumn Header="PropertyName"
                                            Width="*" 
                                            Binding="{Binding PropertyName}" 
                                            ElementStyle="{StaticResource LeftTextCellStyle}" />

                        <DataGridTextColumn Header="PropertyValue" 
                                            Width="300" 
                                            Binding="{Binding PropertyValue}" 
                                            ElementStyle="{StaticResource LeftTextCellStyle}" />

                        <DataGridTextColumn Header="LookupValues"
                                            Width="100" 
                                            Binding="{Binding LookupValue}" 
                                            ElementStyle="{StaticResource LeftTextCellStyle}" />

                    </DataGrid.Columns>
                </DataGrid>

                <Button Name="AddRow"
                        Content="Add Row"
                        DockPanel.Dock="Right"
                        HorizontalAlignment="Right"
                        Margin="20">
                    
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Click">
                            <ei:CallMethodAction TargetObject="{Binding}"
                                         MethodName="PropertiesAddRowButtonClicked" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Button>
Sep 9, 2014 at 7:31 PM
You're not going to want to reference a UI element, such as a data grid, in the view model. The way MVVM works is the other way around - the UI elements are bound to properties in the view model, which fire a PropertyChanged event in each setter.

With regard to your specific issue, you need to bind the ItemsSource property of the data grid to a property on the view model, which is something like an ObservableCollection<T>. You also would need to bind the selected item of the data grid to a property on the view model that represents the current item in the collection. Then your add button would set this current item property on the view model, and because of data binding the grid to move the focus to the new item row.

Download the sample app code for this blog post. I think you will find an example of this behavior there.

Cheers,
Tony
Jan 19, 2015 at 10:14 PM
Simply making the last item the Selected Item does not automatically scroll it into view. At least not withy the grids I'm using (Component One). But what I do is send a message to the View using NotificationEventsArg. The programming reference on it is easy to follow. Write the ScrollIntoView method in code behind, and call it from the ViewModel using Notify, similar to the way you would send a error notice to the view.
Jan 20, 2015 at 2:18 PM
Glad you found a solution. Let me know if there is anything else I can help with.