mkautzm
mkautzm

Reputation: 1146

How do I get the Row Clicked on, not the Row Selected in a WPF Data Grid

I have a column in a DataGrid in XAML that looks like this:

<DataGridTemplateColumn Header="" Width="35" IsReadOnly="True">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Image Source="{Binding PostIcon}" Stretch="None" MouseDown="Post_MouseDown" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

The event that fires is supposed to grab another piece of data in the datagrid row: In this case, a URL code. It then runs this when the event is fired:

    private void Post_MouseDown(object sender, MouseButtonEventArgs e)
    {
        int index = ThreadList.SelectedIndex;
        DataRowView row = (DataRowView)ThreadList.SelectedItems[0];

        string topicID = Convert.ToString(row["URL"]);
        string thisURL = "http://www.myforums.com/perm/topic/" + topicID;

        System.Diagnostics.Process.Start(thisURL);
    }

The idea here is that when you click on an image icon in the data table, it grabs the Index of the row you clicked on, finds the associated thread ID, and builds out the URL and then takes you there.

This all works, except that DataGrid.SelectedItems isn't actually capturing what's clicked on. It's capturing what's selected at the time of the click.

What this means is that if you click on a row, it always ends up selecting what you had previously clicked on, not what you actually just clicked on. How do I make it so it selects what I just clicked on? There doesn't seem to be an obvious 'ClickedItem' equivalent to 'SelectedItems'

--SOLUTION--

The full solution I ended up employing, thanks to AnjumSKhan, looks like this (featuring moving the variable 'dc' to an explicit DataRowView variable):

    private void Post_MouseDown(object sender, MouseButtonEventArgs e)
    {
        int index = ThreadList.SelectedIndex;

        var dc = (sender as Image).DataContext;

        DataRowView row = (DataRowView)dc;

        string topicID = Convert.ToString(row["URL"]);
        string thisURL = "http://www.myforums.com/perm/topic/" + topicID;
        System.Diagnostics.Process.Start(thisURL);
    }

Upvotes: 0

Views: 255

Answers (2)

rmojab63
rmojab63

Reputation: 3631

Handle MouseLeftButtonUp event and try this:

    private void DataGrid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        DependencyObject dep = (DependencyObject)e.OriginalSource; 
        while ((dep != null) && !(dep is DataGridRow))
        {
            dep = VisualTreeHelper.GetParent(dep);
        }

        if (dep is DataGridRow)
        {
            DataGridRow row = dep as DataGridRow;
            // do something
        }
    } 

Upvotes: 1

AnjumSKhan
AnjumSKhan

Reputation: 9827

Have you tried this :

private void Post_MouseDown(object sender, MouseButtonEventArgs e)
    {
         var dc = (sender as Image).DataContext;
         ...
    }

Upvotes: 1

Related Questions