【问题标题】:WPF datagrid selected row clicked event ?WPF datagrid 选择行点击事件?
【发布时间】:2011-03-08 10:19:09
【问题描述】:

当双击 WPF DataGrid 的选定行时,我想执行一些代码。我知道数据网格有一个 MouseDoubleClicked 事件,它也有一个行选择事件,但我没有看到“双击选定行”的任何事件......

您认为有可能以某种方式捕获此事件吗?

【问题讨论】:

标签: wpf events datagrid


【解决方案1】:

我在寻找解决方案时提出了这个问题,但无论是由于年龄还是我自己的实施,答案都不起作用。无论哪种方式,这都是对我有用的解决方案。

将 MouseDoubleClick 事件添加到 DataGrid

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

在方法中

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

到目前为止,我还没有发现任何问题。它没有其他人遇到的问题,这意味着双击标题或预先选择的行的空白区域仍然会导致它运行。

【讨论】:

  • 你可能想在返回之前做e.handled = True;
【解决方案2】:

使用数据绑定和 MVVM,您可以像这样执行一键式事件(=行的选定项):

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

代码隐藏:

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

视图模型:

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

    }
        }

【讨论】:

    【解决方案3】:

    ItemContainerStyle没有最佳解决方案,建议使用RowStyle

    在您的 XAML 中:

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

    在您的代码中:

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

    【讨论】:

    • 这似乎更好,但我不确定为什么这是正确的选择 - 谁能更详细地解释一下?
    • 是的,发件人是 DoubleClicked 行,您可以使用 Item 属性访问绑定到该行的模型,就像这样。 if (sender is DataGridRow dataGridRow) { dataGridRow.Item.your_model_property,,,, }
    【解决方案4】:

    您可以在ItemContainerStyle 中添加事件处理程序(即应用于一行的样式):

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

    然后,在处理程序中,您可以检查该行是否被选中

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

    【讨论】:

    • FWIW,我无法让“RoutedEvent”工作。我收到一条错误消息:“在类型 'EventSetter' 中找不到属性 'RoutedEvent'。”我可以通过将 RoutedEvent 更改为 Event 来使其工作。
    • @CoreyCole,你是对的,这是一个错误。感谢您指出。
    • 我发现将它放在`` 中可以在ItemContainerStyle 没有的地方使用。
    • @ThomasLeveseque 行或单元格是否有单击事件?
    • @VK 你可以使用Event="MouseUp"Event="MouseDown"
    【解决方案5】:

    您可以尝试当前单元格更改的事件处理程序,它仅通过单击而不是双击如果您正在寻找,因为双击可用于启动编辑单元格或整行或任何其他过程:

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

    【讨论】:

    • 您应该改用SelectionChanged 事件。所选索引似乎落后于此事件。
    【解决方案6】:

    为什么在 DoubleClick 事件发生时不获取 SelectedRow 属性并对其进行处理?如果 SelectedRow 为空,则表示未选择任何行,因此只需返回

    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
    }
    

    【讨论】:

    • 这行不通。用户可以先选择行,然后在空白区域双击。
    猜你喜欢
    • 1970-01-01
    • 2017-07-23
    • 2015-07-17
    • 1970-01-01
    • 2012-01-15
    • 2011-01-20
    • 1970-01-01
    • 2019-02-09
    • 2012-02-03
    相关资源
    最近更新 更多