开发者

disabling a window

In my application I have a Button. If the button is clicked as select against a database is executed and the result is shown in a ListView. As the select is quite complex, it takes some time to retrieve the data.

When I click the Button, the Application-Window should be disabled until the data is loaded. But when I set the IsEnabled-Property of the Window to false, the window gets disabled after the data is loaded.

I tried to disable the Window in an other thread with a BackgroundWorker. But then I get an exception that the window is already in use by another thread.

How can I disable the Window bev开发者_StackOverflow中文版ore it retrieves the data?


You did the wrong thing in a background thread. You have to affect the UI from the UI thread, and your data loading should occur in a background thread.

The simplest approach is to use a BackgroundWorker to load your data, store that data in a class-level variable, and when your background work is complete, the UI re-enables and loads the data from the class-level variable.


I'd think you'd move the database activity to the background thread to leave your UI responsive (even if it's only to disable it) rather than the other way around.


try this:

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;


I will suggest "BusyDialog" window in addition to background thread.

Yous busy dialog can be an animation displaying it is doing something, and modally blocking any user input as well.

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;
        });
    }

}

Now you can use following way to call your method asynchronously,

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

This is what happens,

  1. BusyDialog is displayed modally, blocking any user input as well as displaying busy animation
  2. A call to your method MyLongDatabaseLoadingCall is executed in ThreadPool.QueueUserItem, which asynchronously calls your method in different thread (Same as background threading functionality suggested by others here).
  3. Animation continues till the call is executing
  4. When your method ends, BusyDialog is ended and everything is back to how it was.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜