I am trying to work out independent  roll-over  and click behavior between rows in a DataGrid and graphics on a GraphicsLayer, where GraphicsLayer and DataGrid have same data source.  The Spatial Query sample comes close, however it selects on mouseover rather than just highlighting.  I don't want to do this because I want to select only on a click, and want to maintain that selction regardless of what features are rolled over with the mouse.So the behavior I want is (the hard part is the highlighting - the selection is actually pretty easy):
- Clicking on a graphic SELECTS the corresponding row in datagrid.
 
- Clicking on a row in datagrid SELECTS the corresponding graphic.
 
- Mouseover a graphic highlights (but does not select) the corresponding row in datagrid.
 
- Mouseover a row in datagrid highlights (but does not select) the corresponding graphic.
 
I almost have this working - I am able to change the visual state of the DataGrid when rolling over a graphic, using VisualStateManager. However I cannot do the same to change graphic's visual state on DataGrid row rollover, because VisualStateManager.GoToState requires a Control as input and Graphic inherits from DependencyObject.  So is there some other way to set the graphic's visual state?Here are the MouseEnter/Leave events for the Graphic, to set the DataGridRow - these work:private void graphicsLayer_MouseLeave(object sender, GraphicMouseEventArgs e)
{
 DataGridRow row = getDataGridRowByDataContext(dgGeofences, e.Graphic);
 if (dgGeofences.SelectedItem == e.Graphic)
  VisualStateManager.GoToState(row, "Normal Selected", true);
 else
  VisualStateManager.GoToState(row, "Normal", true);
}
private void graphicsLayer_MouseEnter(object sender, GraphicMouseEventArgs e)
{
 // Highlight on rollover
 DataGridRow row = getDataGridRowByDataContext(dgGeofences, e.Graphic);
 VisualStateManager.GoToState(row, "MouseOver", true);
}Here is what I want to do for the MouseEnter/Leave events for the DataGridRow - but cannot pass graphic to VisualStateManager:private void Row_MouseLeave(object sender, MouseEventArgs e)
{
 DataGridRow row = sender as DataGridRow;
 Graphic graphic = row.DataContext as Graphic;
 VisualStateManager.GoToState(graphic, "Normal", true); // Compile Error - graphic is not a Control
}
private void Row_MouseEnter(object sender, MouseEventArgs e)
{
 DataGridRow row = sender as DataGridRow;
 Graphic graphic = row.DataContext as Graphic;
 VisualStateManager.GoToState(graphic, "MouseOver", true); // Compile Error - graphic is not a Control
}For the sake of completeness, here is the method I use to get the DataGridRow corresponding to a graphic (this turned out to be tricky in and of itself, but I found this approach online):private DataGridRow getDataGridRowByDataContext(DataGrid dataGrid, object dataContext) {
 if (null != dataContext)     
 {         
  dataGrid.ScrollIntoView(dataContext, null);
  DataGridAutomationPeer automationPeer = (DataGridAutomationPeer)DataGridAutomationPeer.CreatePeerForElement(dataGrid);         
  // Get the DataGridRowsPresenterAutomationPeer so we can find the rows in the data grid...
  DataGridRowsPresenterAutomationPeer dataGridRowsPresenterAutomationPeer = automationPeer.GetChildren().Where(a => (a is DataGridRowsPresenterAutomationPeer)).Select(a => (a as DataGridRowsPresenterAutomationPeer)).FirstOrDefault();
  if (null != dataGridRowsPresenterAutomationPeer)
  {
   foreach (var item in dataGridRowsPresenterAutomationPeer.GetChildren())             
   {                 
    // loop to find the DataGridCellAutomationPeer from which we can interrogate the owner -- which is a DataGridRow
    foreach (var subitem in (item as DataGridItemAutomationPeer).GetChildren())
    { 
     if ((subitem is DataGridCellAutomationPeer))
     {
      // At last -- the only public method for finding a row.... 
      DataGridRow row = DataGridRow.GetRowContainingElement(((subitem as DataGridCellAutomationPeer).Owner as FrameworkElement)); 
      // check this row to see if it is bound to the requested dataContext.
      if ((row.DataContext) == dataContext) 
      {
       return row; 
      } 
      break; // Only need to check one cell in each row 
     }  
    }
   }
  }
 } 
 return null; 
}