使用MVVM,我们应该在哪里进行启用或禁用UI的调用?

时间:2016-11-25 14:17:51

标签: c# wpf mvvm

我很好奇实现以下内容的最优雅方式是什么。

我有一个后台工作程序,它可以加载进度条UI,并在运行查询时更新它的状态。发生这种情况时,主应用程序在后台禁用 这样用户就无法触摸它。完成后,进度条结束,并再次启用主应用程序UI。我的问题是,在UI线程中执行此工作的最佳方式是什么。

现在,我将MainWindow(main ui)的一个实例传递给后台工作者并在那里执行启用/禁用:

    public static void RunQuery(WorkerArguments workerArgs, MainWindow mw)
    {
        BackgroundWorkerInitialize();       // initialize BackgroundWorker events

        mainWindow = mw;
        stopWatch = new Stopwatch();        // create a new stopwatch
        queryLoading = new QueryLoading();  // create a new QueryLoading screen
        queryLoading.Owner = mainWindow;    // set queryLoading owner to MainWindow (results in QueryLoading UI loading in the center of mainUI)

        mainWindow.SetIsEnabled(false);     // disable the main UI 
        queryLoading.Show();                // show the query loading screen
        backgroundWorker.RunWorkerAsync(workerArgs);    // do the work
    }

    private static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        // We need to check e.Error to find out if any exceptions were thrown in Do_Work
        if (e.Error != null)
        {
            ExceptionHandler.ExceptionHandlingUtility.DisplayExceptionUI(e.Error.ToString(), mainWindow);
        }

        else
        {        
            ObservableCollection<Client> clients = (ObservableCollection<Client>)e.Result;  // cast result to ObvservableCollection<Client>

            queryLoading.Close();           // close loading ui
            mainWindow.SetIsEnabled(true);  // enable the main UI
            stopWatch = null;
            mainWindow.DisplaySearchResults(clients); // display our results
            BackgroundWorkerCleanup();      // cleanup background worker events
            }
    }

有没有更好或更清洁的方法来做到这一点,它对我来说感觉不对。我在考虑将我的ViewModel作为参数而不是MainWindow发送,并在我的viewModel中使用方法 将启用/禁用该应用程序。我还是需要对viewModel的引用,以便我可以传回从搜索查询返回的客户端。

SetIsEnabled方法是我在MainWindow.xaml.cs中创建的一个方法,现在回顾它可能是不必要的冗余。

    /**
     * SetIsEnabled
     *  Sets the IsEnabled property of main UI
     * Args:
     *  isEnabled - boolean value to set isEnabled
     **/
    public void SetIsEnabled(bool isEnabled)
    {
        this.IsEnabled = isEnabled;
    }

2 个答案:

答案 0 :(得分:2)

正如其他人所建议的:在ViewModel上公开一个属性并将IsEnabled绑定到它,这是一种干净的方法。

如果要禁用的控件支持命令,也可以在ViewModel上实现一个Command,当后台工作者忙时调用CanExecute时返回'false':How to use the CanExecute Method from ICommand on WPF

答案 1 :(得分:1)

我认为您想在视图模型中创建新的Boolean属性,将该bool属性绑定在IsEnabled的XAML文件属性中。根据您的视图模型中的条件设置真假,不要传递视图。