views:

582

answers:

2

I have a bound DataGrid and various other controls(external to the datagrid) that show more details about the selectedrow in the datagrid. This is easy to do with databinding or handling the SelectionChanged event on the datagrid.

However, how do I do this without requiring the user to select a row - eg on 'mouseover' can I change the selected item or get the row/item 'under' the mouse.

+1  A: 

Try something like this in your container class like UserControl, Grid, StackPanel, etc...

public class MyContainerClass : FrameworkElement
{
    public MyContainerClass()
    {
         base.Loaded += OnLoaded;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
     m_DataGrid.MouseMove += OnMouseMove;
    }

    private void OnMouseMove(object sender, MouseEventArgs e)
    {
     DataGridRow item = (sender as DependencyObject).ParentOfType<DataGridRow>();
     if (item != null && m_DataGrid.SelectedIndex != item.GetIndex())
      m_DataGrid.SelectedIndex = item.GetIndex();
    }
}

And add this helper class extension...

internal static class DependencyObjectExt
{
    // Extension for DependencyObject
    internal static TT ParentOfType<TT>(this DependencyObject element) where TT : DependencyObject
    {
     if (element == null)
      return default(TT);

     while ((element = VisualTreeHelper.GetParent(element)) != null)
     {
      if (element is TT)
       return (TT)element;
     }

     return null;
    }
}

Jim McCurdy
A: 

Here is a simpler but less generic implementation of Jim's answer. In VB.Net:

Private Sub DataGrid1_LoadingRow(ByVal sender As Object, ByVal e As System.Windows.Controls.DataGridRowEventArgs) Handles DataGrid1.LoadingRow
    AddHandler e.Row.MouseEnter, AddressOf row_MouseEnter
End Sub

Private Sub row_MouseEnter(ByVal sender As Object, ByVal e As MouseEventArgs)
        Dim row = CType(sender, DataGridRow)
        Me.DataGrid1.SelectedItem = CType(row.DataContext, MyType)
End Sub
geoff