繁体   English   中英

WPF更新网格可见性

[英]WPF Update grid visibility

在网上进行一些搜索后,我设置了这个简单的例子:

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行模仿一些工作,这需要一些时间来完成。 工作开始之前,网格应该变得可见,并显示有关该工作的一些信息,并在工作完成后折叠。

好吧,你应该考虑在一个单独的线程上执行Thread.Sleep(1000)操作,而不是在UI线程上。 检查为。 除此之外,在将其visibility设置为collapsed后,尝试使用yourGrid.UpdateLayout()方法。

LE:最有可能的是,他的Thread.Sleep(1000)代表了类似于数据库操作的东西,例如需要时间的东西。

LE2: BackgroundWorker会做到这一点。 检查此链接

如果您使用的是.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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM