我有一个基本的对话窗口,允许用户输入一些信息。单击AddButton
时,应用程序将验证用户信息,并在操作失败时显示消息。按钮旁边有一个静态标签,最初是隐藏的。单击该按钮时,标签在验证操作开始之前变为可见,并且在操作结束后再次变为。请注意,此验证操作发生在远程计算机上,因此UI在此期间冻结(它是按设计)。
这是XAML代码:
<Label Name="lblStatus" Content="Verifying connection..." Visibility="Hidden" Grid.Column="0" />
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Add" Width="80" Margin="0,0,5,0" Click="AddButton_Click"/>
<Button Content="Cancel" Width="80" IsCancel="True"/>
</StackPanel>
代码隐藏:
private void AddButton_Click(object sender, RoutedEventArgs e)
{
lblStatus.Visibility = Visibility.Visible;
// Validation occurs here. The UI is freezed for about 3 seconds
Foo.Validate();
lblStatus.Visibility = Visibility.Hidden;
}
问题是,当单击按钮时,标签在UI冻结之前不会显示。当操作失效时,会弹出一个对话框。此时,您会看到标签,但这是UI醒来的时候。这让我觉得在调用foo.Validate()
时,UI没有足够的时间重新渲染标签。我想知道我的理论是否正确,以及实现这一目标的“正确”方法是什么?
答案 0 :(得分:4)
private void AddButton_Click(object sender, RoutedEventArgs e)
{
lblStatus.Visibility = Visibility.Visible;
Task.Factory.StartNew(()=>
{
Foo.Validate();
OnUi(() => lblStatus.Visibility = Visibility.Hidden);
}
};
}
public static void OnUi (Action action)
{
if (_dispatchService == null) _dispatchService = ServiceLocator.Current.GetInstance<IDispatchService>();
if (_dispatchService.CheckAccess())
action.Invoke ();
else
_dispatchService.Invoke(action);
}
答案 1 :(得分:-1)
之前我遇到过这个问题,以下是我解决的问题:
public class CsUtil
{
public static void DoEvents()
{
Application.Current.Dispatcher.Invoke(
DispatcherPriority.Background,
new ThreadStart(DoNothing));
}
private static void DoNothing()
{
// Just as it says, this method does nothing :-P
}
}
这个类几乎可以从WinForms中获取旧的DoEvents()方法。这基本上创建了一个新线程,调用一个什么都不做的方法然后杀死线程。不知何故,这使得重点关注UI线程并且更新发生得更快。
要使用它,只需执行此操作(在代码隐藏中):
private void AddButton_Click(object sender, RoutedEventArgs e)
{
lblStatus.Visibility = Visibility.Visible;
// Validation occurs here. The UI is freezed for about 3 seconds
CsUtil.DoEvents();
Foo.Validate();
lblStatus.Visibility = Visibility.Hidden;
}
祝你好运,如果它不起作用,请告诉我,
此致
凯尔