Pergunta

Em um WPF UserControl, tenho que fazer para ligar para um serviço da web. Estou fazendo essa chamada em um tópico separado, mas quero informar ao usuário que a chamada pode levar algum tempo.

O webMethod me retorna uma coleção de objetos e eu o vincho a uma caixa de listagem na minha UC. Até agora, tudo bem ... essa parte funciona muito bem. No entanto, Quero exibir uma barra de progresso (ou uma animação de qualquer tipo ...) durante a chamada. Essa animação estaria no topo e centralizada no controle da caixa de listagem.

Eu tentei Adorner e ele funciona parcialmente. No entanto, eu tenho que desenhar todos os controles em substituição protegida vazio onrender (drawercontext drawercontext) ... eu simplesmente quero adicionar um controle por alguns segundos ...

Alguém tem uma idéia de como eu poderia conseguir isso?

Obrigado!

Foi útil?

Solução

Não vá com o Adorner - o que eu faço é ter dois controles de contêineres separados (geralmente grades) que ocupam a mesma área da tela. Um é o meu controle de "progresso" e o outro é o meu controle de "conteúdo". Defino a visibilidade do controle de progresso como colapso e a visibilidade do controle de conteúdo para visível por padrão.

Se você o tiver configurado dessa maneira, quando você inicia a chamada assíncrona para o serviço da web, pode tornar visível o controle de progresso e o controle de conteúdo entrou em colapso. Quando o WebService terminar, use o Dispatcher.BegininVoke para atualizar a interface do usuário e, nesse ponto, alterne o controle de progresso de volta para o colapso e o controle de conteúdo de volta para visível.

Eu geralmente faço o controle do progresso indeterminado. Aqui está um exemplo; Nisso, tenho um UserControl separado chamado ProgressGrid que tem minha barra de progresso.

    <Grid x:Name="layoutRoot">
        <Grid x:Name="contentGrid" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Visible">
             <!-- snip -->
        </Grid>

        <controls:ProgressGrid x:Name="progressGrid" Text="Signing in, please wait..." Visibility="Collapsed"/>
    </Grid>

E no código por trás, apenas algo simples como este:

    private void SignInCommand_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        contentGrid.Visibility = Visibility.Collapsed;
        progressGrid.Visibility = Visibility.Visible;
    }

Outras dicas

Há um truque que você pode usar com uma tela de altura zero que pode funcionar. O livro WPF de Chris Anderson entra em detalhes sobre isso e por que funciona, mas é algo assim.

  • Crie um Stackpanel
  • Adicione uma tela com altura = "0" e um índice Z alto ao painel de pilha
  • Adicione seu controle do usuário ao painel da pilha.

Quando você deseja mostrar a barra de progresso, adicione -a à tela de altura zero. Isso permitirá que você o posicione sobre o controle do usuário. A tela permite que você vá além de suas fronteiras. A centralização da barra de progresso deve exigir apenas a análise das dimensões do controle do usuário e definir a posição da barra de progresso na tela de acordo. Remova a barra de progresso da tela quando terminar.

Aqui está um exemplo simples que usa uma caixa de texto. Não é perfeito, mas mostra a ideia. Clicar no botão mostra a caixa de texto em cima do InkCanvas

<DockPanel LastChildFill="True">
    <Button DockPanel.Dock="Top" Name="showButton" Click="showProgress">show</Button>
    <StackPanel DockPanel.Dock="Bottom">
        <Canvas Name="zeroHeight" Height="0"/>
        <InkCanvas Name="inky">
        </InkCanvas>
    </StackPanel>
</DockPanel>


private void showProgress(object sender, RoutedEventArgs e)
{
    TextBox box = new TextBox();
    box.Text = "on top";
    StackPanel.SetZIndex(zeroHeight, 8);
    zeroHeight.Children.Add(box);
    box.Width = 30;
    box.Height = 30;
    Canvas.SetLeft(box, 10);
    Canvas.SetTop(box, 10);
    Canvas.SetZIndex(box, 10);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top