0

I think this should be fairly simple, but I've been looking through the properties in the signature for the handler that I'm using and I don't see any way to suss out what I'm looking for.

I have a fairly simple WPF app with two DataGrid controls in the same window. I have a double click event defined in the XAML like so:

<DataGrid.ItemContainerStyle>
    <Style TargetType="DataGridRow">
        <EventSetter
            Event="MouseDoubleClick"
            Handler="Row_DoubleClick"/>
    </Style>
</DataGrid.ItemContainerStyle>

And in the code behind (do we call it that in WPF apps?) I have the Row_DoubleClick handler set up like so:

Private Sub Row_DoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs)

Now the sub itself works fine and picks up the row that was double-clicked just fine. However, as I noted before I have two DataGrids that use this same sub for the double-click event. I realize one path might be to simply make two subs, but it seems like I should be able to use the one for both, and it's taking the exact same action in either case, just using the row from one DataGrid or the other.

It always defaults to the first, let's call it IncompleteGrid, if a row is selected even if the second DataGrid, let's call it CompleteGrid, is the the one being double clicked. I've been looking through the sender and e objects in debug mode, but I don't see any place or property I can check to see which grid the double-click is coming from.

Any ideas?

Mike Precup
  • 4,148
  • 21
  • 41
MattB
  • 2,203
  • 5
  • 26
  • 48
  • SENDER is a reference to the grid that was clicked. – Steve Aug 06 '14 at 18:49
  • @Steve `sender` shows up as `System.Windows.Controls.DataGridRow` rather than `System.Windows.Controls.DataGrid`, so I can't get the DataGrid object from it directly. Is there a way to get the hosting DataGrid object from the row? – MattB Aug 06 '14 at 18:54

3 Answers3

1

You can get the parent dataGrid from row by using VisualTreeHelper. Have this private method on your code (code is in C#, hope you can get it convert to VB easily):

private void Row_DoubleClick(object sender, MouseButtonEventArgs e)
{
    DataGridRow row = sender as DataGridRow;
    DataGrid senderDataGrid = FindAncestor<DataGrid>(row);
}

private T FindAncestor<T>(DependencyObject dependencyObject)
    where T : DependencyObject
{
    var parent = VisualTreeHelper.GetParent(dependencyObject);

    if (parent == null) return null;

    var parentT = parent as T;
    return parentT ?? FindAncestor<T>(parent);
}

VB Version:

Private Sub Row_DoubleClick(sender As Object, e As MouseButtonEventArgs)
    Dim row As DataGridRow = TryCast(sender, DataGridRow)
    Dim senderDataGrid As DataGrid = FindAncestor(Of DataGrid)(row)
End Sub

Private Function FindAncestor(Of T As DependencyObject)(dependencyObject As DependencyObject) As T
    Dim parent = VisualTreeHelper.GetParent(dependencyObject)

    If parent Is Nothing Then
        Return Nothing
    End If

    Dim parentT = TryCast(parent, T)
    Return If(parentT, FindAncestor(Of T)(parent))
End Function
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • 1
    Wow, never would have thought of this. Great answer, and thanks for the translation. I think I would have been able to sort it out from the C#, we just write in VB around here for some reason, but it's very helpful. Works perfectly! Thanks again! – MattB Aug 06 '14 at 21:30
0

sender should be the grid that the double-click is coming from. (That's the meaning of sender -- the control that sent the event.)

You can cast sender to a DataGrid if you want to do specific stuff with it.

Edit: If sender is a DataGridRow instead of a DataGrid, then you could use this question to find the host DataGrid. (Using a RelativeSource or a CommandParameter seems to the accepted methods for this.)

Community
  • 1
  • 1
Jashaszun
  • 9,207
  • 3
  • 29
  • 57
  • Sender appears as "DataGridRow" rather than the "DataGrid" object, so no dice there - unless there is a way that you can get the host datagrid from the "DataGridRow" object. – MattB Aug 06 '14 at 18:50
0

This parameter should give you the information:

ByVal sender As System.Object
Yair Nevet
  • 12,725
  • 14
  • 66
  • 108
  • Sender appears as "DataGridRow" rather than the "DataGrid" object. Already took a peek at that one. – MattB Aug 06 '14 at 18:51