c# – 当应用程序通过UI自动化测试启动时,ContentControl不可见,
我们正在使用棱镜和
WPF来构建应用程序.最近我们开始使用UI自动化(UIA)来测试我们的应用程序.但是当我们运行UIA测试时,会发生一些奇怪的行为.这是简化的shell:
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Name="loadingProgressText" VerticalAlignment="Center" HorizontalAlignment="Center" Text="Loading,please wait..."/> <Border Grid.Row="0" x:Name="MainViewArea"> <Grid> ... </Grid> </Border> <!-- Popup --> <ContentControl x:Name="PopupContentControl" Grid.Row="0" prism:RegionManager.RegionName="PopupRegion" Focusable="False"> </ContentControl> <!-- ErrorPopup --> <ContentControl x:Name="ErrorContentControl" Grid.Row="0" prism:RegionManager.RegionName="ErrorRegion" Focusable="False"> </ContentControl> </Grid> 在我们的应用程序中,我们使用层(Popup和ErrorPopup)来隐藏MainViewArea,以拒绝对控件的访问.要显示弹出窗口,我们使用下一个方法: //In constructor of current ViewModel we store _popupRegion instance to the local variable: _popupRegion = _regionManager.Regions["PopupRegion"]; //--- private readonly Stack<UserControl> _popups = new Stack<UserControl>(); public void ShowPopup(UserControl popup) { _popups.Push(popup); _popupRegion.Add(PopupView); _popupRegion.Activate(PopupView); } public UserControl PopupView { get { if (_popups.Any()) return _popups.Peek(); return null; } } 与此类似,我们在应用程序的所有元素上显示ErrorPopup: // In constructor we store _errorRegion: _errorRegion = _regionManager.Regions["ErrorRegion"] // --- private UserControl _error_popup; public void ShowError(UserControl popup) { if (_error_popup == null) { _error_popup = popup; _errorRegion.Add(_error_popup); _errorRegion.Activate(_error_popup); } } Mistics … 当用户执行它(双击应用程序图标)时,我们可以看到两个自定义控件(使用AutomationElement.FindFirst方法,或通过Visual UI Automation Verify).但是当我们使用UI自动化测试启动它时,ErrorPopup从控件树中消失.我们试图启动这样的应用程序: System.Diagnostics.Process.Start(pathToExeFile); 我想我们错过了一些东西.但是呢 编辑#1 正如@chrismead所说,我们试图运行我们的应用程序,UseShellExecute标志设置为true,但这并没有帮助.但是,如果我们从cmd行启动应用程序,并手动单击按钮,Popup和ErrorPopup在自动化控件树中可见. Thread appThread = new Thread(delegate() { _userAppProcess = new Process(); _userAppProcess.StartInfo.FileName = pathToExeFile; _userAppProcess.StartInfo.WorkingDirectory = System.IO.Directory.GetCurrentDirectory(); _userAppProcess.StartInfo.UseShellExecute = true; _userAppProcess.Start(); }); appThread.SetApartmentState(ApartmentState.STA); appThread.Start(); 我们的建议之一是当我们使用FindAll或FindFirst方法来搜索按钮以单击,窗口以某种方式缓存其UI自动化状态,并且不更新它. 编辑#2 在MainViewArea中,我们有一个ContentControl,它根据用户操作更新内容,我们只能看到第一个加载的ContentControl到ContentControl.Content属性.这样执行: IRegionManager regionManager = Container.Resolve<IRegionManager>(); regionManager.RequestNavigate(RegionNames.MainContentRegion,this.Uri); 如果我们更改视图,则在UI自动化树中不会执行任何更新 – 第一个加载的视图将被替换.但是在视觉上我们观察到另一个视图,而WPFInspector显示它正确(它的显示不是UI自动化树),但是Inspect.exe – 不是. 另外我们建议窗口使用某种缓存是错误的 – 在UI Automation客户端中缓存,我们必须明确地打开,但是我们不这样做. 解决方法
对不起,我错过了一些细节,那是答案的关键.我认为这不重要.无论如何.
我们从DevExpress控件库中使用NavBar进行WPF.事实证明,当NavBar存在时,动态创建的视图不会出现在UI自动化树中.当从窗口中删除它时,可以看到所有动态加载的视图. NavBar是什么 – 对我来说还是很重要的. 这个明亮的例子,看看发生了什么,如果NavBar在窗口中出现或不存在(需要DevExpress). MainWindow.xaml: <Window xmlns:dxn="http://schemas.devexpress.com/winfx/2008/xaml/navbar" x:Class="Test.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" > <Grid Name="ContentGrid"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <!--Comment NavBar to see dynamic control in UI Automation tree--> <dxn:NavBarControl Name="asdasd"> <dxn:NavBarControl.Groups> <dxn:NavBarGroup Header="asdasdasdasd" /> </dxn:NavBarControl.Groups> </dxn:NavBarControl> <TextBox Grid.Column="1" Name="Statictb" Text="static is visible in ui automation tree" /> <Button Grid.Row="1" Content="Create controls" Height="25" Click="Button_Click"/> </Grid> </Window> MainWindow.xaml.cs public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Button_Click(object sender,RoutedEventArgs e) { TextBox tb = new TextBox(); Grid.SetRow(tb,1); Grid.SetColumn(tb,1); tb.Text = "dynamic is not visible,if NavBar here..."; ContentGrid.Children.Add(tb); } } 编辑 根据DevExpress answer在他们的支持网站:
这解决了这个问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |