Search code examples
c#wpfdatagridwpfdatagrid

How do get the location of a WPF DataGrid cell?


I have a DataGrid bound to a collection of Appointment objects. The grid shows appointments for a given week, with columns as days, and rows as times, ergo each cell is bound to an appointment.

When the user single clicks a cell, I want to show a small window with a summary of that cell's appointment. For reasons complex, I can't template the cell to show the summary, and more important, I want the summary to drop down and overlay the cells below the selected one.

In my command linked to the single-click, through some magic, I get the DataGridCellInfo for the selected cell itself, but that object offers no hint of any positioning, only some dimensions. The input binding for double-click looks like this:

<DataGrid.InputBindings>
    <!--TODO Remove name 'TheGrid' and find parent DataGrid-->
    <MouseBinding MouseAction="LeftDoubleClick"  Command="{Binding ApptClickCommand}" CommandParameter="{Binding ElementName=TheGrid, Path=SelectedCells}" />
</DataGrid.InputBindings>

and the command code receives a parameter of type SelectedCellsCollection, which contains only one DataGridCellInfo. I have no other information to work with in the command. As it is, I'm cheating quite a bit being so intimate with the view inside the viewmodel, so I'd like to avoid going overboard and using code-behind events directly.


Solution

  • Here is an example of how you could get the DataGridCell element and then find its screen coordinates using the Visual.PointToScreen method:

        private void AppClickCommandExecuted(IList<DataGridCellInfo> cells)
        {
            if(cells != null && cells.Count > 0)
            {
                DataGridCellInfo cellInfo = cells[0];
                FrameworkElement cellContent = cellInfo.Column.GetCellContent(cellInfo.Item);
                if (cellContent != null)
                {
                    DataGridCell cell = cellContent.Parent as DataGridCell;
                    if(cell != null)
                    {
                        Point screenCoordinates = cell.PointToScreen(new Point(0, 0));
                        //place your popup based on the screen coordinates of the cell...
                    }
                }
            }
        }