ContentControl não é visível quando o aplicativo é iniciado por meio do teste de Automação da Interface do Usuário, mas é visível quando o aplicativo é iniciado pelo usuário

Estamos usando o prisma e o WPF para criar aplicativos. Recentemente, começamos a usar a UI Automation (UIA) para testar nosso aplicativo. Mas algum comportamento estranho ocorreu quando corremos o teste UIA. Aqui está o shell simplificado:

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

Em nosso aplicativo, usamos camadas (Popup eErrorPopup) esconderMainViewArea, para negar acesso aos controles. MostrarPopup, usamos o próximo método:

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

Similar a isso, mostramosErrorPopup sobre todos os elementos da nossa aplicação:

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

Mística ...

Quando executamos isso como os usuários fazem (clique duas vezes no ícone do aplicativo), podemos ver ambos os controles personalizados (usandoAutomationElement.FindFirst método, ou através deAutomação de interface do usuário visual). Mas quando começamos usando o teste de Automação da Interface do Usuário -ErrorPopup desaparece da árvore dos controles. Estamos tentando iniciar o aplicativo assim:

System.Diagnostics.Process.Start(pathToExeFile);

Eu acho que perdemos alguma coisa. Mas o que?

Editar # 1

Como disse @chrismead, tentamos executar nosso aplicativo comUseShellExecute flag definido como true, mas isso não ajuda. Mas se começarmos o aplicativo decmd linha e clique manualmente no botão,Popup eErrorPopup são visíveis na árvore de controles de automação.

    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();

Uma de nossas sugestões é quando usamos o métodoFindAll ouFindFirst para pesquisar o botão para clicar, janela de alguma forma armazenada em cache seu estado de automação da interface do usuário e não atualizá-lo.

Editar # 2 Nós encontramos, esse método de extensão da biblioteca de prismasIRegionManager.RegisterViewWithRegion(RegionNames.OurRegion, typeof(Views.OurView)) tem algum comportamento estranho. Se paramos de usá-lo, isso resolve nosso problema particularmente. Agora podemos ver ErrorView e qualquer tipo de visualização emPopupContentControle aplicativo atualiza a estrutura da árvore de elementos UIA. Mas isso não é uma resposta - "Basta parar de usar esse recurso"!

EmMainViewArea nós temos umaContentControl, que atualiza o conteúdo de acordo com as ações do usuário, e podemos ver apenas o primeiro carregadoUserControl para issoContentControl.Content propriedade. Isso é feito assim:

IRegionManager regionManager = Container.Resolve<IRegionManager>();
regionManager.RequestNavigate(RegionNames.MainContentRegion, this.Uri);

E se alterarmos a exibição, nenhuma atualização será executada na árvore de Automação da Interface do Usuário - a primeira exibição carregada estará nela. Mas visualmente observamos outraVieweWPFInspector mostra-lo corretamente (seu show não uma árvore de automação de interface do usuário), mas Inspect.exe - não.

Além disso, nossa sugestão de que a janela use algum tipo de armazenamento em cache está errada - o armazenamento em cache no cliente de Automação da Interface do Usuário precisa ser ativado explicitamente, mas não o fazemos.

questionAnswers(3)

yourAnswerToTheQuestion