2008-12-01 1 views
8

В WPF UserControl я должен сделать для вызова WebService. Я делаю этот вызов в отдельном потоке, но хочу сообщить пользователю, что вызов может занять некоторое время.Как отобразить индикатор выполнения поверх элемента управления в WPF

WebMethod возвращает мне набор объектов, и я привязываю его к ListBox в своем UC. Пока что так хорошо ... Эта часть работает очень хорошо. Однако, Я хочу отобразить индикатор выполнения (или анимацию любого рода ...) во время вызова. Эта анимация будет сверху и сосредоточена в элементе управления ListBox.

Я пробовал Adorner, и он частично работает. Тем не менее, я должен нарисовать все элементы управления в защищенном переопределении void OnRender (DrawingContext drawingContext) ... Я просто хочу добавить элемент управления на пару секунд ...

У кого-нибудь есть представление о том, как я мог это достичь?

Спасибо!

ответ

9

Не ходите с adorner - у меня есть два отдельных элемента управления контейнерами (обычно это сетки), которые занимают одну и ту же область экрана. Один из них - мой контроль «прогресса», а другой - мой «контент». Я установил видимость контроля выполнения Collapsed и видимость элемента управления содержимым Visible по умолчанию.

Если вы настроили его таким образом, при запуске асинхронного вызова веб-службы вы можете сделать видимый контроль выполнения и управление контентом свернуто. Когда веб-сервис завершается, используйте Dispatcher.BeginInvoke для обновления пользовательского интерфейса, и в этот момент переключите управление выполнением назад на рухнувшее и управление контентом обратно на видимое.

Я обычно делаю контроль прогресса неопределенным. Вот пример; в этом я имею отдельный UserControl под названием ProgressGrid, у которого есть индикатор выполнения.

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

А в коде позади, просто что-то простое, как это:

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

Ничего себе! Отличный ответ! Однако, с вашим решением, как я могу централизовать элемент управления ProgressBar в центре ListBox? Canvas? – Martin 2008-12-01 01:06:43

1

Существует трюк можно использовать с нулевой высоты холста, которые могли бы работать. Книга WPF Криса Андерсона подробно рассказывает об этом и почему она работает, но это происходит примерно так.

  • создать StackPanel
  • добавить холст с Height = «0» и высокий Z-индекс к панели стека
  • добавить пользовательский элемент управления в панели стека.

Если вы хотите показать индикатор выполнения, добавьте его на холст с нулевой высотой. Это позволит вам разместить его над пользовательским элементом управления. Холст позволяет вам выйти за пределы его границ. Центрирование полосы выполнения должно просто потребовать взглянуть на размеры пользовательского элемента управления и соответственно установить положение полосы хода на холсте. Удалите индикатор выполнения с холста, когда закончите.

Вот простой пример, который использует TextBox. Это не идеально, но это показывает идею. Нажатие кнопки показывает TextBox поверх 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); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^