2016-07-27 44 views
2

我們在WebBrowser controlWPF application中託管MS-Word文件。在瀏覽器中託管Word - AutomationElement IsWindowPatternAvailable - 如何設置它?

WebBrowser control顯示了導航過程中所選擇的MS-Word文檔以下對話:

File Download dialogue

我們嘗試關閉編程方式使用AutomationElement對話。代碼在測試應用程序中沒有任何問題。當我們調整實際應用程序中的代碼(edit文件,顯示mail merge文件)時,只有mail merge部分正確關閉對話框。在另一種情況下,找不到對話的AutomationElement。

當對話的AutomationElement有IsWindowPatternAvailable = false時,我們發現我們的代碼失敗。

有沒有辦法預先設置這個屬性?或者爲什麼在一種情況下是對的,而在另一種情況下是錯的?

測試應用程序是一個「標準WPF應用程序」項目。它只包含MainWindow.xaml.cs和MainWindow.xaml。 點擊一個按鈕設置SourceWebBrowser

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; 

       } 
      } 
     } 
    } 

我們的實際應用中是一個比較複雜的,並使用MVVMPRISM 5WCF。我們使用WCF從服務器加載Word文檔。這些文件保存在%temp%中。

兩個ViewModel S(編輯文件/節目合併文檔,在每一個different module)發佈一個event其中View小號訂閱:

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; 
     } 

    } 

我們已經找到了差異IsWindowPatternAvailableinspect.exe幫助。當IsWindowPatternAvailable = true對話是Desktop的直接子,可以找到。當IsWindowPatternAvailable = false我們看不到inspect.exeTreeView中的對話,但我們可以通過單擊它來訪問對話的屬性。 在inspect.exe我們看下面的ancestors

  • 對話本身
  • 元產品類別:殼牌嵌入
  • web瀏覽器
  • ViewEdit(查看編輯文檔)
  • 應用

當我們使用代碼在「合併」模塊中編輯文檔時 - 調整dialo gue被正確關閉。兩個模塊都引用相同的UIAutomation DLL(UIAutomationClient,UIAutomationProvider)。

類似的問題在這裏提到:AutomationElement shows up using Inspect.exe but does show not up ... 使用TreeWalker或搜索AutomationElement.RootElement的完整Subtree不起作用。

任何線索爲什麼IsWindowPatternAvailable表現這種方式是值得歡迎的。關於如何關閉文件下載對話的其他建議也是受歡迎的。

回答

0

最後在使用UIAutomationEvents的blog幫助下找到了解決我的問題的解決方案。

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(); 
     } 
    } 
相關問題