tags:

views:

32

answers:

4
+1  Q: 

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 alreay in use by an other thread.

How can I disable the Window bevore it retrieves the data?

+1  A: 

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.

Lazarus
+2  A: 

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.

Adam Sills
Thank you for your answers.I thought about doing it this way myself.Unfortunately it wasn't that easy, becouse of the design of the application.So I hoped maybe someone would have had an other solution.
Arno Greiler
A: 

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;
Johnny
A: 

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.
Akash Kava