Получить окно WPF от hWnd - PullRequest
13 голосов
/ 28 апреля 2011

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

Ответы [ 4 ]

15 голосов
/ 28 апреля 2011
Window window = (Window)HwndSource.FromHwnd(hWnd).RootVisual
3 голосов
/ 28 апреля 2011

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

1 голос
/ 13 ноября 2013

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

1 голос
/ 28 апреля 2011

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

найти всех детей типа

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's name is set for search
          if (frameworkElement != null && frameworkElement.Name == childName)
          {
            // if the child's name is of the request name
            foundChild = (T)child;
            break;
          }
        }
        else
        {
          // child element found.
          foundChild = (T)child;
          break;
        }
      }

      return foundChild;
    }

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...