我希望在WPF DataGrid中选定某一行后双击该行时可以执行一些代码。我知道datagrid具有MouseDoubleClicked事件和RowSelected事件,但是我没有看到任何“选择的行双击”事件......
你觉得有可能以某种方式捕获这个事件吗?
您可以在 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
}
<DataGrid.RowStyle>
中可以起作用,而ItemContainerStyle
则不行。 - simonalexander2005Event="MouseUp"
或者Event="MouseDown"
。 - The Fluffy Robot在寻找解决方案时,我遇到了这个问题,但答案并没有起作用,可能是因为它们过时了或者我自己的实现有问题。不管怎样,这是对我有效的解决方案。
将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;
。 - simonalexander2005使用数据绑定和MVVM,您可以像这样完成一键事件(=选定行的selectedItem):
<Datagrid ItemsSource="{Binding YourObservableCollectionProperty}"
SelectedItem="{Binding YourSelectedItemProperty}">
//more...
</Datagrid>
CodeBehind:
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.*/
}
}
你可以尝试使用当前单元格变更事件处理程序,它仅在单击一次时起作用,而不是双击,如果这正是你想要的,因为双击可以用于启动编辑单元格或整个行或任何其他过程:
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
事件代替。对于此事件,所选索引似乎滞后了。 - toster-cxItemContainerStyle
没有最佳解决方案,建议使用 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
}
使用 rowstyle
和 MouseDoubleClick
,就像 Darlan Dieterich 所说的那样。
但是当单元格中有 button
、checkbox
或其他控件时,它们会处理事件但不会阻止事件传递到行,导致奇怪的行为。在这些情况下,使用 MouseDown
可能更好。
<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;
}
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
}