MadSeb
MadSeb

Reputation: 8234

WPF datagrid selected row clicked event ?

I want to execute some code when a a selected row of the WPF DataGrid is double clicked. I know that the datagrid has a MouseDoubleClicked event and that it also has a row selected event but I don't see any event for "selected row double clicked" ...

Do you think it's possible to capture this event somehow ?

Upvotes: 48

Views: 119017

Answers (7)

Robin L
Robin L

Reputation: 155

Use rowstyle and MouseDoubleClick work, like Darlan Dieterich said.

But when there are button or checkbox or other controls in cell, they will handle event but not prevent event passing to row, cause weird behavior. Use MouseDown maybe better in these case.

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">        
        <EventSetter Event="MouseDown" Handler="DataGridRow_MouseDown"/>
    </Style>
</DataGrid.RowStyle>
private void DataGridRow_MouseDown(object sender, MouseButtonEventArgs e)
{
    if(e.ClickCount != 2)
    {
        return;
    }
    // code here
            
    e.Handled = true;
}

Upvotes: 0

Gilgamesh
Gilgamesh

Reputation: 498

This question came up for me while looking for a solution and the answers didn't work, whether due to age or my own implementation. Either way, here is the solution that worked for me.

Add the MouseDoubleClick event to the DataGrid

        <DataGrid x:Name="DatagridMovie"
              Width="Auto"
              CanUserAddRows="False"
              CanUserDeleteRows="True"
              IsReadOnly="true"
              ItemsSource="{Binding}"
              MouseDoubleClick="Row_MouseDoubleClick">

and in the method

private void Row_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{                
    // Ensure row was clicked and not empty space
    var row = ItemsControl.ContainerFromElement((DataGrid)sender,
                                        e.OriginalSource as DependencyObject) as DataGridRow;

     if ( row == null ) return;

    … Stuff();
 }

So far I haven't noticed any problems with it. It doesn't share the problem that others have that means double clicking a header or empty space with a row selected beforehand would still cause it to run.

Upvotes: 27

timunix
timunix

Reputation: 629

With data binding and MVVM you would do one-click event (=selectedItem of row) like this:

    <Datagrid ItemsSource="{Binding YourObservableCollectionProperty}" 
        SelectedItem="{Binding YourSelectedItemProperty}"> 
     //more...      
    </Datagrid>

CodeBehind:

public partial class YourClass : Window
    {
        public YourClass()
        {
            InitializeComponent();
            this.DataContext = new YourClassViewModel();                      
        }
}

ViewModel:

public class YourClassViewModel : INotifyPropertyChanged
{

                public event PropertyChangedEventHandler PropertyChanged;
                public virtual void OnPropertyChanged(string propertyName)
                {
                    if (this.PropertyChanged != null)
                    {
                        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                    }
                }

                private ObservableCollection<YourModelClass> _yourObservableCollectionProperty;
                public ObservableCollection<YourModelClass> YourObservableCollectionProperty
                {
                    get { return _yourObservableCollectionProperty; }
                    set
                    {
                        _yourObservableCollectionProperty = value;
                        OnPropertyChanged("YourObservableCollectionProperty");
                    }
                }

    private YourModelClass _yourSelectedItemProperty;
    public YourModelClass YourSelectedItemProperty
    {   
           get { return _yourSelectedItemProperty; }
           set
           {
                _yourSelectedItemProperty = value;
                OnPropertyChanged("YourSelectedItemProperty");
           }    
    }

//Constructor
public YourClassViewModel()
{

       /*Take your ModelClass instance and ObservableCollection instance here 

and play around with them or move them into a method. Normally your 

observablecollection is the itemssource of your datagrid and your selecteditem 

is your modelclass.*/

    }
        }

Upvotes: 6

Darlan Dieterich
Darlan Dieterich

Reputation: 2537

The ItemContainerStyle do not have best solution, suggest use the RowStyle:

In your XAML:

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">        
        <EventSetter Event="MouseDoubleClick" Handler="DataGridRow_MouseDoubleClick"/>
    </Style>
</DataGrid.RowStyle>

In your Code:

private void DataGridRow_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    //your logic here
}

Upvotes: 2

Thomas Levesque
Thomas Levesque

Reputation: 292355

you can add the event handler in the ItemContainerStyle (which is the style applied to a row) :

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

Then, in the handler, you can check if the row is selected

private void Row_DoubleClick(object sender, MouseButtonEventArgs e)
{
    // execute some code
}

Upvotes: 65

0x01Brain
0x01Brain

Reputation: 818

You could try current cell changed event handler it works only with one click and not double click if thats what your looking for, since double click can be used to for initiating editing cell or entire row or for any other process:

private void datagrid_CurrentCellChanged(object sender, EventArgs e)
    {
        int selected_index = datagrid.SelectedIndex + 1;
        // this is used for debugging and testing.
        //MessageBox.Show("The index of the row for the clicked cell is " + selected_index);

    }

Upvotes: 4

Carlo
Carlo

Reputation: 25959

Why don't you get the SelectedRow property while the DoubleClick event happens and do something with it? If the SelectedRow is null, it means no Row is selected so just return

private void Grid_DoubleClick(object sender, RoutedEventArgs e)
{
    if(grid.SelectedRow == null)
        return; // return if there's no row selected

    // do something with the Selected row here
}

Upvotes: 0

Related Questions