簡體   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