在网上进行一些搜索之后,我设置了这个简单的例子:
PropertyChangedBase.cs
public class PropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) {
//Raise the PropertyChanged event on the UI Thread, with the relevant propertyName parameter:
Application.Current.Dispatcher.BeginInvoke((Action)(() => {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}));
}
}
UserViewModel.cs
public class UserViewModel : PropertyChangedBase
{
private Visibility _showUserWindow = Visibility.Collapsed;
public Visibility ShowUserWindow {
get { return _showUserWindow; }
set {
_showUserWindow = value;
OnPropertyChanged("ShowUserWindow"); //This is important!!!
}
}
}
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid Margin="43,28,247,129" Background="AliceBlue" Visibility="{Binding ShowUserWindow}"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="349,150,0,0" VerticalAlignment="Top" Width="75" PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown"/>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
UserViewModel userViewModel;
public MainWindow() {
InitializeComponent();
userViewModel = new UserViewModel();
DataContext = userViewModel;
}
private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
userViewModel.ShowUserWindow = Visibility.Visible;
Thread.Sleep(1000);
userViewModel.ShowUserWindow = Visibility.Collapsed;
}
}
现在网格在1秒后崩溃,我想在计时器启动之前更新UI。我做错了什么?
修改 Thread.Sleep line模仿了一些工作,需要一些时间才能完成。 工作开始前网格应该可见,并显示有关该工作的一些信息,并在工作完成后折叠。
答案 0 :(得分:2)
好吧,您应该考虑在单独的线程上执行 Thread.Sleep(1000)操作,而不是在UI线程上。检查this。
除此之外,请在将yourGrid.UpdateLayout()
设置为visibility
后尝试使用collapsed
方法。
LE:
最有可能的是,他的Thread.Sleep(1000)
代表数据库操作,例如需要时间的东西。
LE2:BackgroundWorker
可以解决问题。检查this link!
答案 1 :(得分:1)
如果您使用的是.NET 4.5,则可以使用Task.Delay()在开始实际工作之前允许UI自行更新:
private async void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
userViewModel.ShowUserWindow = Visibility.Visible;
await Task.Delay(1);
Thread.Sleep(1000);
userViewModel.ShowUserWindow = Visibility.Collapsed;
}
请注意,即使将await Task.Delay(1);
替换为实际工作,也应使用Thread.Sleep(1000)
。
但是,只有当您的工作只能在UI线程中完成并且无法移动到后台线程(例如,大量加载UI元素)时,才应使用此选项。否则,正确的方法是将工作移至后台线程:
private async void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
userViewModel.ShowUserWindow = Visibility.Visible;
await Task.Start(() => {
Thread.Sleep(1000);
};
userViewModel.ShowUserWindow = Visibility.Collapsed;
}