Получить окно WPF hWnd

Я ищу, чтобы получить окно WPF и пройти его элементы управления. Я могу получить hWnd, и я нашел другие сообщения об обходе элементов управления с помощью DependencyObject. Как получить объект DependencyObject из hWnd? Возможно ли это?

Ответ 1

Window window = (Window)HwndSource.FromHwnd(hWnd).RootVisual

Ответ 2

Насколько я знаю, WPF полностью заменяет модель WinApi всеми HWND. Главное окно имеет HWND, конечно, потому что он сервер как контейнер между WinApi и WPF. Вы можете получить доступ к HWND, используя WindowInteropHelper Class, например this. Но вы не сможете перемещать элементы управления так же, как и с помощью собственного или WinForms. Проверьте VisualTreeHelper для перемещения деревьев управления в WPF.

Ответ 3

После того, как вы сами получите окно (как указывает Марат, как это сделать), вам нужно искать визуальное дерево. Вот две вспомогательные функции

найти всех дочерних элементов типа

public static IEnumerable<T> FindChildren<T>(this DependencyObject source) where T : DependencyObject
    {
      if (source != null)
      {
        var childs = GetChildObjects(source);
        foreach (DependencyObject child in childs)
        {
          //analyze if children match the requested type
          if (child != null && child is T)
          {
            yield return (T)child;
          }

          //recurse tree
          foreach (T descendant in FindChildren<T>(child))
          {
            yield return descendant;
          }
        }
      }
    }

https://sites.google.com/site/bobstechwiki/home/wpf-ji-shu-1/find-element-by-visual-tree

чтобы найти ребенка по имени:

 public static T FindChild<T>(DependencyObject parent, string childName)
       where T : DependencyObject
    {    
      // Confirm parent and childName are valid. 
      if (parent == null) return null;

      T foundChild = null;

      int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
      for (int i = 0; i < childrenCount; i++)
      {
        var child = VisualTreeHelper.GetChild(parent, i);
        // If the child is not of the request child type child
        T childType = child as T;
        if (childType == null)
        {
          // recursively drill down the tree
          foundChild = FindChild<T>(child, childName);

          // If the child is found, break so we do not overwrite the found child. 
          if (foundChild != null) break;
        }
        else if (!string.IsNullOrEmpty(childName))
        {
          var frameworkElement = child as FrameworkElement;
          // If the child name is set for search
          if (frameworkElement != null && frameworkElement.Name == childName)
          {
            // if the child name is of the request name
            foundChild = (T)child;
            break;
          }
        }
        else
        {
          // child element found.
          foundChild = (T)child;
          break;
        }
      }

      return foundChild;
    }

Как я могу найти элементы управления WPF по имени или типу?

Ответ 4

Здесь еще не зарегистрирован особый случай. Может быть, что контроль верхнего уровня не является стандартным WPF Window. Это так (например) в Visual Studio 2010. Я обнаружил это при написании надстройки визуальной студии: я хотел добавить некоторые элементы управления WPF в визуальное дерево, но вам нужно начать дерево WPF.

К счастью, есть решение:

  var hwnd = _dte.MainWindow.HWnd;
  var window = HwndSource.FromHwnd((IntPtr)hwnd);
  dynamic customWindow = window.RootVisual;
  UIElement content = customWindow.Content;

Фокус в том, что, объявив customWindow как dynamic, вам не нужно знать или указывать его тип. В хорошем стиле WPF он имеет свойство Content, которое содержит все содержимое окна, и оттуда все нормально.