In an event handler for a Command for a DataGrid, I get DataGridCell in ExecutedRoutedEventArgs. However, I couldn't figure out how to get its associated DataGrid and DataGridRow. Your help is much appreciated.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
You probably want to set some sort of RelativeSource
binding that can get you the "parent grid/row" via a {RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}
, but your question got me thinking...
You could:
Use Reflection:
var gridCell = ....;
var parentRow = gridCell
.GetType()
.GetProperty("RowOwner",
BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(null) as DataGridRow;
Use the VisualTreeHelper
:
var gridCell = ...;
var parent = VisualTreeHelper.GetParent(gridCell);
while(parent != null && parent.GetType() != typeof(DataGridRow))
{
parent = VisualTreeHelper.GetParent(parent);
}
回答2:
Here is what I think is a complete answer...
private void Copy(object sender, ExecutedRoutedEventArgs e)
{
DataGrid grid = GetParent<DataGrid>(e.OriginalSource as DependencyObject);
DataGridRow row = GetParent<DataGridRow>(e.OriginalSource as DependencyObject);
}
private T GetParent<T>(DependencyObject d) where T:class
{
while (d != null && !(d is T))
{
d = VisualTreeHelper.GetParent(d);
}
return d as T;
}
回答3:
One way you could do is by passing one or both of the needed elements in as a CommandParameter:
<MouseBinding
MouseAction="LeftDoubleClick"
Command="cmd:CustomCommands.Open"
CommandParameter="{Binding ElementName=MyDataGrid}}" />
If you need both, you could add a multi-value converter that combines them into a Tuple
(or leave it as an object[])
Then in your code-behind you can access it by using e.Parameter