Это список общедоступных объектов этого модуля, интерпретируемых import *
. Он отменяет умолчание, скрывая все, что начинается с подчеркивания.
Ответ Исака у меня не сработал, потому что он не решил проблему того, как действовать, когда фактическое ожидание истекло для пользователя. Я закончил тем, что сделал это: каждый раз, когда я начинаю делать что-то длительное, я вызываю вспомогательный метод. Этот вспомогательный метод изменяет курсор, а затем создает DispatcherTimer, который будет вызываться, когда приложение бездействует. Когда он вызывается, он возвращает курсор мыши:
/// <summary>
/// Contains helper methods for UI, so far just one for showing a waitcursor
/// </summary>
public static class UiServices
{
/// <summary>
/// A value indicating whether the UI is currently busy
/// </summary>
private static bool IsBusy;
/// <summary>
/// Sets the busystate as busy.
/// </summary>
public static void SetBusyState()
{
SetBusyState(true);
}
/// <summary>
/// Sets the busystate to busy or not busy.
/// </summary>
/// <param name="busy">if set to <c>true</c> the application is now busy.</param>
private static void SetBusyState(bool busy)
{
if (busy != IsBusy)
{
IsBusy = busy;
Mouse.OverrideCursor = busy ? Cursors.Wait : null;
if (IsBusy)
{
new DispatcherTimer(TimeSpan.FromSeconds(0), DispatcherPriority.ApplicationIdle, dispatcherTimer_Tick, Application.Current.Dispatcher);
}
}
}
/// <summary>
/// Handles the Tick event of the dispatcherTimer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private static void dispatcherTimer_Tick(object sender, EventArgs e)
{
var dispatcherTimer = sender as DispatcherTimer;
if (dispatcherTimer != null)
{
SetBusyState(false);
dispatcherTimer.Stop();
}
}
}
Так что мне не нравилось использовать OverrideCursor, потому что у меня было несколько окон, и я хотел, чтобы те, которые в данный момент не выполняли что-либо, имели обычный курсор со стрелкой.
Вот мое решение:
<Window.Style>
<Style TargetType="Window">
<Style.Triggers>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<Setter Property="Cursor" Value="Wait" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Style>
<Grid>
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<Setter Property="IsHitTestVisible" Value="False" /> <!-- Ensures wait cursor is active everywhere in the window -->
<Setter Property="IsEnabled" Value="False" /> <!-- Makes everything appear disabled -->
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<!-- Window controls go here -->
</Grid>
В дополнение к вкладу Исак Саво, вы можете посмотреть на блог Брайана Китинга для рабочего образца.
То, что я делал в прошлом, - это определение логических свойств в модели представления, которые указывают, что выполняется длительный расчет. Например, IsBusy
, для которого установлено значение true при работе и false в режиме ожидания.
Затем в представлении я привязываюсь к этому и отображаю индикатор выполнения, или счетчик, или подобное, пока это свойство имеет значение true. Лично я никогда не устанавливал курсор, используя этот подход, но я не понимаю, почему это невозможно.
Если вам нужен еще больший контроль, а простого логического значения недостаточно, вы можете использовать VisualStateManager , который вы запускаете из своей модели представления. При таком подходе вы можете подробно указать, как должен выглядеть пользовательский интерфейс в зависимости от состояния модели представления.