title: How to stop DataGridRow from selecting if mouse is clicked inside RowDetails
body: <p>I have a <code>DataGrid</code>, in each <code>DataGridRow</code> I have row details, which hold a couple of controls.</p>
  
  <p>What I'd like is, if anything is clicked inside the row details to:<br/>
  - Not select the row, or more accurately, <br/>
  - Change the existing <code>DataGrid</code> selection.</p>
  
  <p>I was thinking along the lines of handling PreviewMouseDown and MouseDown events in a behavior, somehow making the DataGrid skip over the selection process, however not sure how to proceed.</p>
  
  <p>Eventually I'm going to have a TabControl in the details with more info as well, so I also don't want a TabItem click to change the DataGrid's existing selection.</p>
  
  <p>Would there be a way to start the tunnelling of PreviewMouseDown at the Grid "DetailsContainer" level and stop the bubbling of MouseDown at the Grid "DetailsContainer" level</p>
  
  <pre><code>&lt;DataGrid Name="dgAudit"
            CanUserReorderColumns="False"
            CanUserAddRows="False"
            CanUserDeleteRows="False"
            CanUserResizeColumns="False"
            CanUserResizeRows="False"
            CanUserSortColumns="False"
            IsReadOnly="True"
            ItemsSource="{Binding GEOM_ASSET_OC_LIST}"
            VirtualizingPanel.ScrollUnit="Pixel"
            RowDetailsVisibilityMode="Visible"
            &gt;
      &lt;i:Interaction.Behaviors&gt;
          &lt;behaviors:DataGridBehaviors /&gt;
      &lt;/i:Interaction.Behaviors&gt;
  
      &lt;DataGrid.Columns&gt;
          &lt;DataGridTextColumn Header="Asset ID" Binding="{Binding ASSET_ID}" Width="200" /&gt;
          &lt;DataGridTextColumn Header="Asset Type" Binding="{Binding ASSET_TYPE}" Width="200" /&gt;
          &lt;DataGridTextColumn Header="Last Update By" Binding="{Binding LAST_UPDATE_BY}" Width="150" /&gt;
          &lt;DataGridTextColumn Header="Last Update Date" Binding="{Binding LAST_UPDATE_DATETIME, StringFormat=\{0:dd.MM.yy HH:mm:ss tt\}}" Width="150" /&gt;
      &lt;/DataGrid.Columns&gt;
      &lt;DataGrid.RowDetailsTemplate&gt;
          &lt;DataTemplate&gt;
              &lt;Grid Name="DetailsContainer"&gt;
                  &lt;Grid.ColumnDefinitions&gt;
                      &lt;ColumnDefinition Width="*" /&gt;
                      &lt;ColumnDefinition Width="Auto" /&gt;
                  &lt;/Grid.ColumnDefinitions&gt;
                  &lt;TextBlock Name Text="{Binding Notes}" Width="400" HorizontalAlignment="Left" TextWrapping="Wrap"/&gt;
                  &lt;Button Content="Button" Grid.Column="1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/&gt;
              &lt;/Grid&gt;
          &lt;/DataTemplate&gt;
      &lt;/DataGrid.RowDetailsTemplate&gt;
  &lt;/DataGrid&gt;
  </code></pre>
  
  <p>Just a quick mock up of an empty behavior</p>
  
  <pre><code>public class DataGridBehaviors : Behavior&lt;DataGrid&gt;
  {
      protected override void OnAttached()
      {
          base.OnAttached();
          this.AssociatedObject.MouseDown += DataGrid_MouseDown;
          this.AssociatedObject.PreviewMouseDown += DataGrid_PreviewMouseDown;
      }
  
      protected override void OnDetaching()
      {
          this.AssociatedObject.PreviewMouseDown -= DataGrid_PreviewMouseDown;
          this.AssociatedObject.MouseDown -= DataGrid_MouseDown;
          base.OnDetaching();
      }
  
      private void DataGrid_MouseDown(object sender, MouseButtonEventArgs e)
      {
      }
  
      private void DataGrid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
      {
          DependencyObject obj = (DependencyObject)e.OriginalSource;
          DataGridDetailsPresenter RowsDetails = FindParent&lt;DataGridDetailsPresenter&gt;(obj);
          if (RowsDetails != null)
          {
              //Skip over selection, maybe temporarily removed native selection handler???
          }
      }
  
      public static T FindParent&lt;T&gt;(DependencyObject child) where T : DependencyObject
      {
          //get parent item
          DependencyObject parentObject = VisualTreeHelper.GetParent(child);
  
          //we've reached the end of the tree
          if (parentObject == null) return null;
  
          //check if the parent matches the type we're looking for
          T parent = parentObject as T;
          if (parent != null)
              return parent;
          else
              return FindParent&lt;T&gt;(parentObject);
      }
  
      private static T GetVisualChild&lt;T&gt;(DependencyObject parent) where T : Visual
      {
          T child = default(T);
  
          int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
          for (int i = 0; i &lt; numVisuals; i++)
          {
              Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
              child = v as T;
              if (child == null)
              {
                  child = GetVisualChild&lt;T&gt;(v);
              }
              if (child != null)
              {
                  break;
              }
          }
          return child;
      }
  }
  </code></pre>