context: using System;
  using System.Linq;
  using System.Windows;
  using System.Windows.Controls;
  using System.Windows.Controls.Primitives;
  using System.Windows.Data;
  using System.Windows.Input;
  using System.Windows.Media;
  using System.Windows.Media.Media3D;
  using System.Windows.Threading;
  
  namespace MaterialDesignThemes.Wpf
  {
      public static class DataGridAssist
      {
          private static DataGrid _suppressComboAutoDropDown;
  
          public static readonly DependencyProperty AutoGeneratedCheckBoxStyleProperty = DependencyProperty
              .RegisterAttached(
                  "AutoGeneratedCheckBoxStyle", typeof (Style), typeof (DataGridAssist),
                  new PropertyMetadata(default(Style), AutoGeneratedCheckBoxStylePropertyChangedCallback));
  
          private static void AutoGeneratedCheckBoxStylePropertyChangedCallback(DependencyObject dependencyObject,
              DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
          {
              ((DataGrid) dependencyObject).AutoGeneratingColumn += (sender, args) =>
              {
                  var dataGridCheckBoxColumn = args.Column as DataGridCheckBoxColumn;
                  if (dataGridCheckBoxColumn == null) return;
  
                  dataGridCheckBoxColumn.ElementStyle = GetAutoGeneratedCheckBoxStyle(dependencyObject);
              };
          }
  
          public static void SetAutoGeneratedCheckBoxStyle(DependencyObject element, Style value)
          {
              element.SetValue(AutoGeneratedCheckBoxStyleProperty, value);
          }
  
          public static Style GetAutoGeneratedCheckBoxStyle(DependencyObject element)
          {
              return (Style) element.GetValue(AutoGeneratedCheckBoxStyleProperty);
          }
  
          public static readonly DependencyProperty AutoGeneratedEditingCheckBoxStyleProperty = DependencyProperty
              .RegisterAttached(
                  "AutoGeneratedEditingCheckBoxStyle", typeof (Style), typeof (DataGridAssist),
                  new PropertyMetadata(default(Style), AutoGeneratedEditingCheckBoxStylePropertyChangedCallback));
  
          private static void AutoGeneratedEditingCheckBoxStylePropertyChangedCallback(DependencyObject dependencyObject,
              DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
          {
              ((DataGrid) dependencyObject).AutoGeneratingColumn += (sender, args) =>
              {
                  var dataGridCheckBoxColumn = args.Column as DataGridCheckBoxColumn;
                  if (dataGridCheckBoxColumn == null) return;
  
                  dataGridCheckBoxColumn.EditingElementStyle = GetAutoGeneratedEditingCheckBoxStyle(dependencyObject);
              };
          }
  
          public static void SetAutoGeneratedEditingCheckBoxStyle(DependencyObject element, Style value)
          {
              element.SetValue(AutoGeneratedEditingCheckBoxStyleProperty, value);
          }
  
          public static Style GetAutoGeneratedEditingCheckBoxStyle(DependencyObject element)
          {
              return (Style) element.GetValue(AutoGeneratedEditingCheckBoxStyleProperty);
          }
  
          public static readonly DependencyProperty AutoGeneratedEditingTextStyleProperty = DependencyProperty
              .RegisterAttached(
                  "AutoGeneratedEditingTextStyle", typeof (Style), typeof (DataGridAssist),
                  new PropertyMetadata(default(Style), AutoGeneratedEditingTextStylePropertyChangedCallback));
  
          private static void AutoGeneratedEditingTextStylePropertyChangedCallback(DependencyObject dependencyObject,
              DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
          {
              ((DataGrid) dependencyObject).AutoGeneratingColumn += (sender, args) =>
              {
                  var dataGridTextColumn = args.Column as DataGridTextColumn;
                  if (dataGridTextColumn == null) return;
  
                  dataGridTextColumn.EditingElementStyle = GetAutoGeneratedEditingTextStyle(dependencyObject);
              };
          }
  
          public static void SetAutoGeneratedEditingTextStyle(DependencyObject element, Style value)
          {
              element.SetValue(AutoGeneratedEditingTextStyleProperty, value);
          }
  
          public static Style GetAutoGeneratedEditingTextStyle(DependencyObject element)
          {
              return (Style) element.GetValue(AutoGeneratedEditingTextStyleProperty);
          }
  
          public static readonly DependencyProperty CellPaddingProperty = DependencyProperty.RegisterAttached(
              "CellPadding", typeof (Thickness), typeof (DataGridAssist),
              new FrameworkPropertyMetadata(new Thickness(13, 8, 8, 8), FrameworkPropertyMetadataOptions.Inherits));
  
          public static void SetCellPadding(DependencyObject element, Thickness value)
          {
              element.SetValue(CellPaddingProperty, value);
          }
  
          public static Thickness GetCellPadding(DependencyObject element)
          {
              return (Thickness) element.GetValue(CellPaddingProperty);
          }
  
          public static readonly DependencyProperty ColumnHeaderPaddingProperty = DependencyProperty.RegisterAttached(
              "ColumnHeaderPadding", typeof (Thickness), typeof (DataGridAssist),
              new FrameworkPropertyMetadata(new Thickness(8), FrameworkPropertyMetadataOptions.Inherits));
  
          public static void SetColumnHeaderPadding(DependencyObject element, Thickness value)
          {
              element.SetValue(ColumnHeaderPaddingProperty, value);
          }
  
          public static Thickness GetColumnHeaderPadding(DependencyObject element)
          {
              return (Thickness) element.GetValue(ColumnHeaderPaddingProperty);
          }
  
  
          public static readonly DependencyProperty EnableEditBoxAssistProperty = DependencyProperty.RegisterAttached(
              "EnableEditBoxAssist", typeof (bool), typeof (DataGridAssist),
              new PropertyMetadata(default(bool), EnableCheckBoxAssistPropertyChangedCallback));
  
          public static void SetEnableEditBoxAssist(DependencyObject element, bool value)
          {
              element.SetValue(EnableEditBoxAssistProperty, value);
          }
  
          public static bool GetEnableEditBoxAssist(DependencyObject element)
          {
              return (bool) element.GetValue(EnableEditBoxAssistProperty);
          }
  
          private static void EnableCheckBoxAssistPropertyChangedCallback(DependencyObject dependencyObject,
              DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
          {
              var dataGrid = dependencyObject as DataGrid;
              if (dataGrid == null) return;
  
              if ((bool) dependencyPropertyChangedEventArgs.NewValue)
                  dataGrid.PreviewMouseLeftButtonDown += DataGridOnPreviewMouseLeftButtonDown;
              else
                  dataGrid.PreviewMouseLeftButtonDown -= DataGridOnPreviewMouseLeftButtonDown;
          }
  
          private static void DataGridOnPreviewMouseLeftButtonDown(object sender,
              MouseButtonEventArgs mouseButtonEventArgs)
          {
              var dataGrid = (DataGrid) sender;
  
              var inputHitTest =
                  dataGrid.InputHitTest(mouseButtonEventArgs.GetPosition((DataGrid) sender)) as DependencyObject;
  
              while (inputHitTest != null)
              {
                  var dataGridCell = inputHitTest as DataGridCell;                
                  if (dataGridCell != null && dataGrid.Equals(dataGridCell.GetVisualAncestry().OfType<DataGrid>().FirstOrDefault()))
                  {
                      if (dataGridCell.IsReadOnly) return;
  
                      ToggleButton toggleButton;
                      ComboBox comboBox;
                      if (IsDirectHitOnEditComponent(dataGridCell, mouseButtonEventArgs, out toggleButton))
                      {
                          dataGrid.CurrentCell = new DataGridCellInfo(dataGridCell);
                          dataGrid.BeginEdit();
                          toggleButton.SetCurrentValue(ToggleButton.IsCheckedProperty, !toggleButton.IsChecked);
                          dataGrid.CommitEdit();
                          mouseButtonEventArgs.Handled = true;
                      }
                      else if (IsDirectHitOnEditComponent(dataGridCell, mouseButtonEventArgs, out comboBox))
                      {
                          if (_suppressComboAutoDropDown != null) return;
  
                          dataGrid.CurrentCell = new DataGridCellInfo(dataGridCell);
                          dataGrid.BeginEdit();
                          //check again, as we move to  the edit  template
                          if (IsDirectHitOnEditComponent(dataGridCell, mouseButtonEventArgs, out comboBox))
                          {
                              _suppressComboAutoDropDown = dataGrid;
                              comboBox.DropDownClosed += ComboBoxOnDropDownClosed;
                              comboBox.IsDropDownOpen = true;
                          }
                          mouseButtonEventArgs.Handled = true;
                      }
  
                      return;
                  }
  
                  inputHitTest = (inputHitTest is Visual || inputHitTest is Visual3D)
                      ? VisualTreeHelper.GetParent(inputHitTest)
                      : null;                
              }
          }
  
          private static void ComboBoxOnDropDownClosed(object sender, EventArgs eventArgs)
          {
              _suppressComboAutoDropDown.CommitEdit();
              _suppressComboAutoDropDown = null;
              ((ComboBox)sender).DropDownClosed -= ComboBoxOnDropDownClosed;
          }
  
          private static bool IsDirectHitOnEditComponent<TControl>(ContentControl contentControl, MouseEventArgs mouseButtonEventArgs, out TControl control)
              where TControl : Control
          {
              control = contentControl.Content as TControl;
              if (control == null) return false;
  
              var frameworkElement = VisualTreeHelper.GetChild(contentControl, 0) as FrameworkElement;
  
gt:             if (frameworkElement == null) return false;