我有一个DataDrid,其RowDetailsVisibilityMode设置为" VisibleWhenSelected"以便在选择特定行时显示RowDetailsTemplate。我想要的是当我再次单击该行时能够切换RowDetails可见性。默认情况下,RowDetails只要选中就会显示,但我想基本上"取消选择"如果我再次单击它,所选行。
在尝试了很多事情之后,我发现了一种古怪的解决方案,至少可以让我在单击该行时切换可见性:
private async void DataGrid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
await Task.Delay(1); //ensures DataGrid.SelectedIndex is what I just clicked, not the previous value
if (DataGrid.SelectedIndex == prevSelectedIndex) { //check if I'm clicking on what's already selected
DataGrid.SelectedIndex = -1; //collapses everything
}
prevSelectedIndex = DataGrid.SelectedIndex; //save current selected index
}
当我检查所选索引时,延迟确保已更新SelectedIndex属性。我希望我没有必要使用它 - 我很乐意找到更好的解决方案。
现在的问题是,每当我单击所选行的RowDetails中的任何内容时,此事件将触发,行详细信息将再次消失。我希望能够以某种方式检查我在单击行本身时只展开/折叠行,而不是在我单击RowDetailsTemplate中的任何内容时。那可能吗?我不想为每一行使用额外的Expander按钮。
答案 0 :(得分:2)
我找到了解决问题的方法:
在ContentControl下的RowDetailsTemplate中,我添加了一个捕获PreviewMouseDown事件的EventSetter:
<EventSetter Event="PreviewMouseDown" Handler="ContentControl_PreviewMouseDown" />
事件的处理程序设置了一个全局变量,表明我是否点击了ContentControl中的内容:
private void ContentControl_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
ClickedRowDetails = true;
}
最后,在我的原始代码中,我只是检查了我是否点击了ContentControl,或者是否是其他东西,在这种情况下,这意味着它就是行本身:
private async void DataGrid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
ClickedRowDetails = false; //default assume that we haven't clicked row details
await Task.Delay(1); //wait for other events to fire
if (!ClickedRowDetails) {
if (DataGrid.SelectedIndex == prevSelectedIndex )
{
DataGrid.SelectedIndex = -1;
}
prevSelectedIndex = DataGrid.SelectedIndex;
}
}
现在,我可以通过简单地单击它们来成功地展开/折叠行,然后我可以操作RowDetailsTemplate中的任何内容而不会意外地折叠该行。这是在没有扩展器按钮的情况下完成的。
答案 1 :(得分:0)
我认为全局布尔变量可以为你做切换。
public bool Visible = false;
private async void DataGrid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (Visible == false)
{
await Task.Delay(1); //ensures DataGrid.SelectedIndex is what I just clicked, not the previous value
if (DataGrid.SelectedIndex == prevSelectedIndex)
{ //check if I'm clicking on what's already selected
DataGrid.SelectedIndex = 1; //collapses everything
}
prevSelectedIndex = DataGrid.SelectedIndex; //save current selected index
Visible = true;
}
else
{
await Task.Delay(1); //ensures DataGrid.SelectedIndex is what I just clicked, not the previous value
if (DataGrid.SelectedIndex == prevSelectedIndex)
{ //check if I'm clicking on what's already selected
DataGrid.SelectedIndex = -1; //collapses everything
}
prevSelectedIndex = DataGrid.SelectedIndex; //save current selected index
Visible = false;
}
}