开发者

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" ... 开发者_StackOverflow中文版

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


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
}


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.


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.*/

    }
        }


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);

    }


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
}


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
}


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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜