我们在MS-Word
的WebBrowser control
中托管WPF application
文档。WebBrowser control
在导航到选定的MS-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 5
和WCF
。我们使用WCF从服务器加载Word文档。文件保存在%temp%中。两个
ViewModel
(编辑文档/显示合并的文档,每个都在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;
}
}
我们已经借助
IsWindowPatternAvailable
找到了inspect.exe
中的区别。当IsWindowPatternAvailable = true
时,对话框是Desktop
的直接子级,可以找到。当IsWindowPatternAvailable = false
时,在TreeView
的inspect.exe
中看不到对话框,但是我们可以通过单击来访问对话框的属性。在
inspect.exe
中,我们看到以下ancestors
:对话本身
元素类名称:Shell嵌入
网页浏览器
ViewEdit(查看以编辑文档)
应用
当我们使用代码在“合并”模块中编辑文档时,对话框将正确关闭。这两个模块都引用相同的
UIAutomation
DLL(UIAutomationClient,UIAutomationProvider)。这里提到了类似的问题:AutomationElement shows up using Inspect.exe but does show not up ...
使用
TreeWalker
或搜索Subtree
的完整AutomationElement.RootElement
无效。欢迎任何
IsWindowPatternAvailable
如此行为的线索。也欢迎提供有关如何关闭“文件下载”对话框的其他建议。 最佳答案
最终使用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();
}
}