0

I have a DataGrid that has RowDetailsVisibilityMode set to "VisibleWhenSelected" so that the RowDetailsTemplate displays when I select a particular row. What I want is to be able to toggle the RowDetails visibility when I click the row again. By default, the RowDetails will be visible so long as its selected, but I want to essentially "unselect" the selected row if I click it again.

After trying a lot of things, I've found a sort of wacky solution that at least makes it so that I can toggle the visibility when I click the row:

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
}

The delay makes sure that the SelectedIndex property is already updated when I check for the selected index. I wish I didn't have to use it - I would be happy to find a better solution.

The problem now, however, is that whenever I click anything in the RowDetails of the selected row, this event fires and the row details disappear again. I want to be able to somehow check that I only expand/collapse the row when I click the row itself, not when I click whatever's in the RowDetailsTemplate. Is that possible? I don't want to use an extra Expander button for each row.

Drew Jex
  • 845
  • 2
  • 13
  • 24
  • Possible duplicate of [I need the Expand / Collapse for RowDetailsTemplate](https://stackoverflow.com/questions/3829137/i-need-the-expand-collapse-for-rowdetailstemplate) – ASh Jul 07 '17 at 14:42
  • Thanks for the response. Question: Doesn't that require a button in a separate column to collapse/expand? Is it possible to implement something similar when I just click the row itself? – Drew Jex Jul 07 '17 at 14:47
  • while it may be more work. Could you re-write the rowTemplate to popup details when clicked? then when you click off it goes away. Unless you absolutely need the info to be with the RowDetailsTemplate, is an alternative possible? – Ginger Ninja Jul 07 '17 at 14:47
  • An alternative may be possible in the future if I can't get this to work, but at least for now the client I'm working with wants it done how it is described unfortunately. – Drew Jex Jul 07 '17 at 14:50

2 Answers2

2

I found a solution to my problem:

In my RowDetailsTemplate under the ContentControl, I added an EventSetter that captured the PreviewMouseDown event:

<EventSetter Event="PreviewMouseDown" Handler="ContentControl_PreviewMouseDown" />

The Handler for the event set a global variable that indicated whether I had clicked on what's in the ContentControl:

private void ContentControl_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    ClickedRowDetails = true;
}

Finally, in my original code, I simply checked whether I had clicked on the ContentControl, or whether it was something else, which in this case, meant it was the row itself:

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

So now, I can successfully expand/collapse rows by simply clicking on them, and then I can manipulate whatever's in the RowDetailsTemplate without accidently collapsing the row. This was done without an Expander button.

Drew Jex
  • 845
  • 2
  • 13
  • 24
0

I think a global boolean variable can do the toggle for you.

        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;
            }
        }
Yousuf Hossain
  • 172
  • 1
  • 12
  • Thanks for the response. I can get my datagrid to toggle, but the main problem at this point is that I want it to toggle only when the row itself is clicked, not when I click the row details below. – Drew Jex Jul 07 '17 at 14:55