尝试通过在WPF中运行某些其他进程来更新UI时,ProgressRing不可见

6g8kf2rb  于 2023-01-02  发布在  其他
关注(0)|答案(1)|浏览(174)

我正在使用WPF应用程序。我在应用程序中使用MahApps Metro控件和主题。我想在其他进程运行时显示加载指示器。此进程也将更新UI。问题是加载指示器不显示。

<mah:ProgressRing x:Name="loadingIndicator" Grid.RowSpan="2" 
                          Foreground="{DynamicResource AccentColorBrush}"
                          IsActive="{Binding IsLoading}" />

private async void ExecuteButton_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        if (DataContext is ExecutionWindowViewModel viewModel)
        {
            if (outputTab.Items.Count > 0)
            {
                outputTab.Items.Clear();
            }
            var selectedDatabases = viewModel.Databases.Where(x => x.IsSelected == true).ToList();
            viewModel.IsLoading = true;
            await Task.Run(() =>
            {
                this.Dispatcher.Invoke(new Action(() =>
                {
                    foreach (var database in selectedDatabases)
                    {
                        TabItem tabItem = new TabItem();
                        tabItem.Header = database.DBShortName;
                        DataGrid sqlOutput = new DataGrid();
                        sqlOutput.AutoGenerateColumns = true;
                        sqlOutput.IsReadOnly = true;
                        var test = viewModel.SQLQueryExecution(database.ConnectionString);
                        sqlOutput.ItemsSource = viewModel.SQLQueryExecution(database.ConnectionString).AsDataView();
                        tabItem.Content = sqlOutput;
                        outputTab.Items.Add(tabItem);
                    }
                }));
            });
            viewModel.IsLoading = false;
        }
    }

加载特性类似于

private bool _isLoading = false;
    public bool IsLoading
    {
        get => _isLoading;
        set
        {
            if (_isLoading != value)
            {
                _isLoading = value;
                OnPropertyChanged(nameof(IsLoading));
            }
        }
    }

在按钮Click事件上,我希望执行多个SQL查询,并基于结果创建多个选项卡。

有人能告诉我为什么ProgressRing不可见吗?
我还尝试了下面的代码,它工作正常,

private async void ExecuteButton_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        if (DataContext is ExecutionWindowViewModel viewModel)
        {
            if (outputTab.Items.Count > 0)
            {
                outputTab.Items.Clear();
            }
            var selectedDatabases = viewModel.Databases.Where(x => x.IsSelected == true).ToList();
            
            viewModel.IsLoading = true;
            await Task.Delay(10000);
            viewModel.IsLoading = false;
        }
    }
xwbd5t1u

xwbd5t1u1#

可以像您那样在不同的任务中执行数据库访问。但是您不应该像以前那样使用调度程序调用方法。当您使用调度程序时,数据库访问是在UI线程下完成的,它会阻止UI更新。当任务运行时,你可以使用调度器调用来更新UI相关的属性。2这样你就不会因为冗长的SQL调用而阻塞UI,并且仍然可以更新UI。IsLoading属性实际上立即设置为false!序列如下:任务正在启动,它向调度程序发送要执行的操作,任务正在终止并将IsLoading设置为false。之后,SQL部分将在UI线程下使用之前设置的操作执行。
我包含了一个稍微修改过的工作代码。

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ProgressBar Grid.Row="0" IsIndeterminate="{Binding IsLoading}" />
        <TabControl Grid.Row="1" Name="outputTab"/>
        <Button Grid.Row="2" Click="Button_Click" Width="100">Load</Button>
    </Grid>

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new ExecutionWindowViewModel();
        }
        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            if (DataContext is ExecutionWindowViewModel viewModel)
            {
                if (outputTab.Items.Count > 0)
                {
                    outputTab.Items.Clear();
                }
                var selectedDatabases = viewModel.Databases;
                viewModel.IsLoading = true;
                await Task.Run(() =>
                {
                        foreach (var database in selectedDatabases)
                        {
                            
                            viewModel.SQLQueryExecution();
                            
                            this.Dispatcher.BeginInvoke((Action)(() => {
                                DataGrid sqlOutput = new DataGrid();
                                sqlOutput.AutoGenerateColumns = true;
                                sqlOutput.IsReadOnly = true;
                                TabItem tabItem = new TabItem();
                                tabItem.Header = database.ToString();
                                tabItem.Content = sqlOutput;
                                outputTab.Items.Add(tabItem); }));

                        }
                        this.Dispatcher.BeginInvoke((Action)(() => { viewModel.IsLoading = false; }));
                    
                });
                
            }
        }
    }



public class ExecutionWindowViewModel: INotifyPropertyChanged
    {
        public ExecutionWindowViewModel()
        {
            Databases = new List<string>();
            Databases.Add("DB1");
            Databases.Add("DB2");
            Databases.Add("DB3");
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged( String propertyName )
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        bool _isLoading;
        public bool IsLoading
        {
            get { return _isLoading; }
            set {
                    _isLoading = value;
                    NotifyPropertyChanged(nameof(IsLoading));
                }
        }
        public List<string> Databases { get; set; }

        public  void  SQLQueryExecution()
        {
            Thread.Sleep(3000);
        }

    }

相关问题