Как отобразить индикатор выполнения поверх элемента управления в WPF
в WPF UserControl я должен сделать вызов веб-службы. Я делаю этот вызов в отдельном потоке, но я хочу, чтобы сообщить пользователю, что вызов может занять некоторое время.
WebMethod возвращает мне коллекцию объектов, и я привязываю ее к списку в моем UC. Пока все идет хорошо... Эта часть работает очень хорошо. Однако,Я хочу отобразить индикатор выполнения (или анимацию любого вида...) во время разговора. Эта анимация будет сверху и по центру в списке управление.
Я попробовал Adorner, и он частично работает. Однако я должен нарисовать все элементы управления в protected override void OnRender (DrawingContext drawingContext)... Я просто хочу добавить элемент управления на пару секунд...
У кого-нибудь есть идея, как я мог бы этого достичь?
спасибо!
2 ответов
не идите с adorner-то, что я делаю, это два отдельных элемента управления контейнером (обычно сетки), которые занимают ту же область экрана. Один из них-мой контроль "прогресса", а другой-мой контроль" содержания". Я установил видимость элемента управления прогрессом в Collapsed и видимость элемента управления контентом в Visible по умолчанию.
Если вы настроили его таким образом, при запуске асинхронного вызова веб-службы вы можете сделать контроль выполнения видимым и содержимое контроль рухнул. Когда webservice завершится, используйте диспетчер.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;
}
есть трюк, который вы можете использовать с холстом нулевой высоты, который может работать. Книга Криса Андерсона WPF подробно рассказывает об этом и почему она работает, но она идет примерно так.
- создать StackPanel
- добавьте холст с высотой= " 0 " и высоким Z-индексом на панель стека
- добавить пользовательский элемент управления на панели стека.
Если вы хотите показать индикатор выполнения, добавьте его на холст нулевой высоты. Это позволит вам поместите его над пользователя. Холст позволяет выйти за его пределы. Центрирование индикатора выполнения должно просто требовать просмотра размеров пользовательского элемента управления и установки положения индикатора выполнения на холсте соответственно. Когда закончите, удалите индикатор выполнения с холста.
вот простой пример, который использует текстовое поле. Это не идеально, но это показывает идею. При нажатии на кнопку отображается текстовое поле поверх 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);
}