禁用窗口

时间:2010-05-20 13:16:06

标签: c# wpf multithreading window

在我的应用程序中,我有一个Button。如果单击该按钮,则执行针对数据库的选择,结果显示在ListView中。 由于选择非常复杂,因此检索数据需要一些时间。

单击Button时,应禁用应用程序 - Window,直到加载数据。 但是当我将窗口的IsEnabled - 属性设置为false时,窗口会在加载数据后被禁用。

我尝试在Window的其他帖子中禁用BackgroundWorker。但后来我得到一个例外,该窗口已经被另一个线程使用了。

如何禁用它检索数据的Window bevore?

4 个答案:

答案 0 :(得分:2)

你在后台线程中做错了什么。您必须从UI线程影响UI,并且您的数据加载应该在后台线程中进行。

最简单的方法是使用BackgroundWorker加载数据,将数据存储在类级变量中,当后台工作为complete时,UI会重新启用并加载来自类级变量的数据。

答案 1 :(得分:1)

我认为你会将数据库活动转移到后台线程,以使你的UI保持响应(即使它只是禁用它),而不是相反。

答案 2 :(得分:0)

试试这个:

BackgroundWorkerHelper.DoWork<Type of object you want to retrieve>(
                   () =>
                   {
                      //Load your data here
                      //Like
                        using (MarketingService svc = new MarketingService())
                        {
                            return svc.GetEmployeeLookupTable();
                        }
                   },
                       (args) =>
                       {
                           this.IsEnable = true;
                           if (args.Error == null)
                           {
                               Your Target Datasource= args.Result;
                           }
                       });

this.IsEnable = false;

答案 3 :(得分:0)

除了背景线程之外,我还建议使用“BusyDialog”窗口。

Yous busy对话框可以是显示正在执行操作的动画,也可以模拟阻止任何用户输入。

public partial class BusyDialog : Window
{
    public BusyDialog()
    {
        InitializeComponent();
    }

    public static T Execute<T>(DependencyObject parent, Func<T> action)
    {

        Window parentWindow = null;
        if (parent is Window)
        {
            parentWindow = parent as Window;
        }
        else
        {
            parentWindow = Window.GetWindow(parent);
        }

        T val = default(T);
        Exception le = null;
        BusyDialog bd = new BusyDialog();
        bd.Owner = parentWindow;
        ThreadPool.QueueUserWorkItem((o) =>
        {
            try
            {
                val = action();
            }
            catch (Exception ex)
            {
                le = ex;
            }
            bd.EndDialog();
        });
        bd.ShowDialog();
        if (le != null)
        {
            Trace.WriteLine(le.ToString());
            throw new Exception("Execute Exception", le);
        }
        return val;
    }

    private void EndDialog()
    {
        Dispatcher.Invoke((Action)delegate() {
            this.DialogResult = true;
        });
    }

}

现在,您可以使用以下方式异步调用方法

List<Result> results = BusyDialog.Execute( this , 
   ()=>{
       return MyLongDatabaseLoadingCall();
   });

这就是发生的事情,

  1. BusyDialog以模态方式显示,阻止任何用户输入以及显示忙碌动画
  2. 调用您的方法MyLongDatabaseLoadingCall在ThreadPool.QueueUserItem中执行,它在不同的线程中异步调用您的方法(与此处其他人建议的背景线程功能相同)。
  3. 动画一直持续到通话正在执行
  4. 当你的方法结束时,BusyDialog会结束,一切都回到原来的状态。