我需要在用户单击WPF DataGrid的详细信息行时折叠它,并在用户再次单击时重新显示它。我还希望使用单选保留VisibleWhenSelected的DataGridRoDetailsVisibilityMode。
我想到了这个解决方案,基于这篇文章在其他地方:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0a45b3a7-46d0-45a9-84b2-0062f07f6fec#eadc8f65-fcc6-41df-9ab9-8d93993e114c
private bool _rowSelectionChanged;
private void dgCompletedJobs_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_rowSelectionChanged = true;
}
private void dgCompletedJobsMouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
DependencyObject dep = (DependencyObject)e.OriginalSource;
//navigate up the tree
while (dep != null &&
!(dep is DataGridCell) &&
!(dep is DataGridColumnHeader))
{
dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null)
{
return;
}
DataGridCell dgc = dep as DataGridCell;
if (dgc != null)
{
//navigate further up the tree
while (dep != null && !(dep is DataGridRow))
{
dep = VisualTreeHelper.GetParent(dep);
}
DataGridRow dgr = dep as DataGridRow;
DataGrid dg = sender as DataGrid;
if (dg != null && dgr != null)
{
if (dgr.IsSelected && !_rowSelectionChanged)
{
dg.RowDetailsVisibilityMode =
(dg.RowDetailsVisibilityMode == DataGridRowDetailsVisibilityMode.VisibleWhenSelected)
? DataGridRowDetailsVisibilityMode.Collapsed
: DataGridRowDetailsVisibilityMode.VisibleWhenSelected;
}
else
{
dg.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.VisibleWhenSelected;
}
}
}
_rowSelectionChanged = false;
}
这似乎很好地解决了我的问题,但我一直怀疑这可以做得更简单和优雅,特别是因为我在这个项目中使用了MVVM。然而,我认为这是事件驱动的代码隐藏的一种可接受的用法,因为它是纯粹的表示逻辑。
有人有更干净的解决方案吗?
4条答案
按热度按时间ct2axkht1#
要使用“适当的”MVVM执行此操作,您应该将RowDetailsVisibilityMode绑定到视图模型上的一个属性:
您的视图模型属性如下所示:
要将鼠标单击事件链接到属性的更改,您可以执行一些附加的行为命令,如here所示,或者使用代码直接调用视图模型(对于简单的任务,我自己经常这样做):
khbbv19g2#
为什么不使用sender参数呢?如果事件是在DataGrid上定义的,那么发送方总是DataGrid!使用安全强制转换来检查空值是安全的,但这应该可以解决问题。
当您通过可视树从原始源返回到DataGrid时,代码似乎不必要地复杂。
njthzxwz3#
我想出了一个不同的方法,但不是一个“适当的”MVVM的方式,因为它使用代码背后(如上面提出的答案中的一些代码),但它只需要几行代码。
通过针对PreviewMouseUp事件编写代码,我能够获得我所需要的确切行为。代码确保您实际上单击了网格中的某个内容,并且要折叠它,必须是已经打开的同一行。
v09wglhw4#
这结合了格拉菲克斯的答案和Prethen的答案。
如果希望仅在已选择行时切换行详细信息,请使用该选项: