2

我们在 a中托管MS-Word文档。WebBrowser controlWPF application

在导航到选定的WebBrowser controlMS-Word 文档期间显示以下对话框:

文件下载对话框

我们尝试使用 以编程方式关闭对话AutomationElement。该代码在测试应用程序中没有任何问题。当我们在我们的实际应用程序中调整代码时(edit文件,显示文件mail merge),只有mail merge部分正确地关闭了对话。在另一种情况下,无法找到对话的 AutomationElement。

我们发现,当对话的 AutomationElement 具有IsWindowPatternAvailable = false.

有没有办法提前设置这个属性?或者为什么它在一种情况下为真而在另一种情况下为假的原因?

测试应用程序是一个“标准 WPF 应用程序”项目。它只包含 MainWindow.xaml.cs 和 MainWindow.xaml。单击按钮Source设置WebBrowser:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Thread thread = new Thread(new ThreadStart(backgroundCheck));
        thread.Start();
        this.TestBrowser.Source = new Uri(@"path-to-document.doc");
        thread.Abort();  
    }

backgroundCheck搜索特定对话并调用Open按钮

    private void backgroundCheck()
    {
        Thread.Sleep(500);
        while (true)
        {

            AutomationElement window = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));

            if (window!= null)
            {
                AutomationElement downloadWindow = window.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));

               if (downloadWindow != null)
                {
                    AutomationElement button = downloadWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "4426"));

                    button.SetFocus();
                     (InvokePattern)button.GetCurrentPattern(InvokePattern.Pattern)).Invoke();
                     return;

                }
            }
        }
    }

我们的实际应用程序要复杂一些,并且使用MVVM,PRISM 5WCF. 我们使用 WCF 从服务器加载 Word 文档。文件保存在 %temp% 中。

两个ViewModels(编辑文档/显示合并文档,每个都在 a 中different module)发布s 订阅的一个eventView

    public class VmExample
    {
        public delegate void BrowserNavigationEventHandler(string pfad);

        public event BrowserNavigationEventHandler browserNavigate;

        private void navigateToDocument()
        {
             browserNavigate("Path-To-Document.doc"); 
        }
    }

    public partial class ViewMerge : UserControl
    {

        private VmExample _vm;

        public ViewMerge()
        {
            InitializeComponent();
            this.DataContextChanged += ViewMerge_DataContextChanged;
        }

        private void ViewMerge_DataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
        {
            this._vm = e.NewValue as VmExample;

            this._vm.browserNavigate += ViewMerge_browserNavigate;
            this.DataContextChanged -= ViewMerge_DataContextChanged;
        }

        private void ViewMerge_browserNavigate(string path)
        {
            Thread threadCheckDownoadWindow = new Thread(backgroundCheck);
            threadCheckDownoadWindow.Start();
            this.wbBrowser.Source = new Uri(path);
            threadCheckDownoadWindow.Abort();
            this._vm.browserNavigate -= ViewMerge_browserNavigate;
        }

    }

我们在IsWindowPatternAvailable的帮助下发现了不同之处inspect.exe。当IsWindowPatternAvailable = true对话是直接子的Desktop并且可以被找到。当IsWindowPatternAvailable = false我们在 of 中看不到对话时,TreeView我们inspect.exe可以通过单击它来访问对话的属性。在inspect.exe我们看到以下内容ancestors

  • 对话本身
  • 元素类名:壳嵌入
  • 网页浏览器
  • ViewEdit(查看以编辑文档)
  • 应用

当我们使用代码在“合并”模块中编辑文档时,对话框正确关闭。两个模块都引用相同的UIAutomationDLL(UIAutomationClient、UIAutomationProvider)。

这里提到了一个类似的问题: AutomationElement 使用 Inspect.exe 显示,但没有显示... 使用 aTreeWalker或搜索完整SubtreeAutomationElement.RootElement不起作用。

欢迎任何线索为什么IsWindowPatternAvailable会这样。也欢迎有关如何关闭文件下载对话框的其他建议。

4

1 回答 1

0

终于在这篇博客的帮助下使用 UIAutomationEvents找到了我的问题的解决方案。

    AutomationEventHandler UIAEventHandler = new AutomationEventHandler(OnUIAEvent);

    Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent,
                    AutomationElement.RootElement,
                    TreeScope.Descendants, UIAEventHandler);
    private static void OnUIAEvent(object src, AutomationEventArgs e)
    {
        AutomationElement element = src as AutomationElement;

        if (element == null)
        {
            return;
        }

        AutomationElement openButton = element.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "4426"));

        if (openButton != null)
        {
            openButton.SetFocus();

            ((InvokePattern)openButton.GetCurrentPattern(InvokePattern.Pattern)).Invoke();
        }
    }
于 2016-08-09T06:01:48.910 回答