private void mainBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            DataEditorActionResult result = (DataEditorActionResult)e.Result;

            if (e.Error != null)
            {
                // Throw on windows forms thread.
                Invoke(
                    (MethodInvoker) delegate()
                {
                    throw new Exception(
                        "An error occured while running the background worker.", e.Error);
                }
                    );
            }

            handleAfterDataAction(result);
        }
        private void mainBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            DataEditorActionArgs actionArgs = (DataEditorActionArgs)e.Argument;
            DataActionEventArgs  eventArgs  = new DataActionEventArgs(actionArgs.Data);

            switch (actionArgs.Action)
            {
            case DataEditorAction.Load:
                OnLoadAsync(eventArgs);
                break;

            case DataEditorAction.Save:
            case DataEditorAction.SaveClose:
            {
                OnSaveAsync(eventArgs);

                switch (editorMode)
                {
                case DataEditorMode.Create:
                    OnCreateAsync(eventArgs);
                    break;

                case DataEditorMode.Update:
                    OnUpdateAsync(eventArgs);
                    break;
                }
            }
            break;
            }

            DataEditorActionResult result = new DataEditorActionResult(
                eventArgs.Data,
                actionArgs.StatusGuid,
                eventArgs.Cancelled,
                eventArgs.UserMessage,
                actionArgs.Action);

            e.Result = result;
        }
        private void handleAfterDataAction(DataEditorActionResult result)
        {
            DataActionAfterEventArgs eventArgs = new DataActionAfterEventArgs(
                result.StatusGuid, result.Cancelled, result.Data);

            switch (result.Action)
            {
            case DataEditorAction.Load:
                OnAfterLoadAsync(eventArgs);
                break;

            case DataEditorAction.Save:
            case DataEditorAction.SaveClose:
            {
                OnAfterSaveAsync(eventArgs);

                switch (editorMode)
                {
                case DataEditorMode.Create:
                    OnAfterCreateAsync(eventArgs);
                    break;

                case DataEditorMode.Update:
                    OnAfterUpdateAsync(eventArgs);
                    break;
                }

                // Ensure form can close.
                changesSaved = true;

                // When cancelled, do not change mode or close.
                if (!result.Cancelled)
                {
                    switch (result.Action)
                    {
                    case DataEditorAction.SaveClose:
                        Close();
                        break;

                    case DataEditorAction.Save:
                        editorMode = DataEditorMode.Update;
                        break;
                    }
                }
            }
            break;
            }

            if (IsHandleCreated)
            {
                if (AutoChangeStatus)
                {
                    // Only revert when window is still alive.
                    AsyncStatusRevert(result.StatusGuid);
                }

                // Not sure if this is so elegant.
                if (DisplayUserMessageAfter &&
                    result.Cancelled &&
                    !string.IsNullOrEmpty(result.UserMessage))
                {
                    MessageBox.Show(
                        result.UserMessage,
                        "Cancelled",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Warning);
                }
            }

            suspendChangeMadeNotify = false;
        }
        private void runActionAsyncMainEvents(DataEditorAction action, object data)
        {
            DataActionBeforeEventArgs beforeArgs = new DataActionBeforeEventArgs(data);

            switch (action)
            {
            case DataEditorAction.Load:
            {
                if (AutoChangeStatus)
                {
                    beforeArgs.StatusGuid = AsyncStatusChange("Loading...");
                }
                OnBeforeLoadAsync(beforeArgs);
            }
            break;

            case DataEditorAction.Save:
            case DataEditorAction.SaveClose:
            {
                if (AutoChangeStatus)
                {
                    beforeArgs.StatusGuid = AsyncStatusChange("Saving...");
                }

                OnBeforeSaveAsync(beforeArgs);

                switch (editorMode)
                {
                case DataEditorMode.Create:
                    OnBeforeCreateAsync(beforeArgs);
                    break;

                case DataEditorMode.Update:
                    OnBeforeUpdateAsync(beforeArgs);
                    break;
                }
            }
            break;
            }

            if (!beforeArgs.Cancel)
            {
                DataEditorActionArgs args = new DataEditorActionArgs(
                    beforeArgs.Data,
                    beforeArgs.StatusGuid,
                    action);

                mainBackgroundWorker.RunWorkerAsync(args);
            }
            else
            {
                DataEditorActionResult result = new DataEditorActionResult(
                    beforeArgs.Data,
                    beforeArgs.StatusGuid,
                    true,
                    string.Empty,
                    action);

                handleAfterDataAction(result);
            }
        }