单击DataGridRow时隐藏和显示RowDetails之间切换

时间:2017-07-07 14:41:26

标签: c# wpf datagrid

我有一个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按钮。

2 个答案:

答案 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;
            }
        }