Esempio n. 1
0
        public void EndApplyChanges(CancelRoutedEventArgs bargs)
        {
            if (bargs.Cancel)
            {
                return;
            }

            if (bargs.Skip)
            {
                if (bargs.CloseDialog)
                {
                    this.Close();
                }

                return;
            }

            // Update final content, if it is null it means it's already been updated
            if (this.TargetContent != null && this._bindings != null)
            {
                foreach (BEData bdata in _bindings)
                {
                    // Get current val
                    object val         = bdata.Obj.GetValue(bdata.Prp);
                    object datacontext = (bdata.Obj as FrameworkElement).DataContext;

                    // Change the data context
                    (bdata.Obj as FrameworkElement).DataContext = this.TargetContent;

                    // Set the value back to the textbox, and update the permanent source
                    bdata.Obj.SetValue(bdata.Prp, val);
                    bdata.Exp.UpdateSource();

                    // Restore the temp. content
                    (bdata.Obj as FrameworkElement).ClearValue(FrameworkElement.DataContextProperty);
                }
            }

            // Raise the post-apply event, this is for validations and persistence
            CancelRoutedEventArgs aargs = new CancelRoutedEventArgs();

            aargs.RoutedEvent = AppliedChangesEvent;
            aargs.Source      = this;
            aargs.CloseDialog = bargs.CloseDialog;
            OnAppliedChanges(aargs);

            // Close the dialog if necessary
            if (bargs.CloseDialog && !aargs.Cancel)
            {
                this.Close();
            }
        }
Esempio n. 2
0
        public void EndApplyChanges(CancelRoutedEventArgs bargs)
        {
            if (bargs.Cancel)
            {
                return;
            }

            if (bargs.Skip)
            {
                if (bargs.CloseDialog)
                {
                    this.Close();
                }

                return;
            }

            // Update final content, if it is null it means it's already been updated
            if (this.TargetContent != null && this._bindings != null)
            {
                // If target is a list, apply changes to all of them
                IEnumerable targetItems;
                if (this.TargetContent is IEnumerable)
                {
                    targetItems = this.TargetContent as IEnumerable;
                }
                else
                {
                    targetItems = new object[] { this.TargetContent }
                };

                ApplyBindingsToItems(targetItems);
            }

            // Raise the post-apply event, this is for validations and persistence
            CancelRoutedEventArgs aargs = new CancelRoutedEventArgs();

            aargs.RoutedEvent = AppliedChangesEvent;
            aargs.Source      = this;
            aargs.CloseDialog = bargs.CloseDialog;
            OnAppliedChanges(aargs);

            // Close the dialog if necessary
            if (bargs.CloseDialog && !aargs.Cancel)
            {
                this.Close();
            }
        }
Esempio n. 3
0
        /// <summary>
        ///
        /// </summary>
        public bool Close()
        {
            // Raise the confirmation event
            CancelRoutedEventArgs args = new CancelRoutedEventArgs();

            args.RoutedEvent = ClosingEvent;
            args.Source      = this;
            OnClosing(args);

            if (args.Cancel)
            {
                return(false);
            }

            // Don't mark as changed while applying changes
            this.Content = null;
            SetValue(TargetContentProperty, null);
            IsOpen = false;

            return(true);
        }
        /// <summary>
        ///
        /// </summary>
        protected static void Dialog_AppliedChanges <RowType>(FloatingDialog dialog, string editingDialogTitle, ListView hostListView, int minPosition, CancelRoutedEventArgs e)
            where RowType : DataRow
        {
            // All went well, so just accept changes
            RowType      finalRow = dialog.TargetContent as RowType;
            DataRowState state    = finalRow.RowState;

            finalRow.Table.AcceptChanges();
            (dialog.Content as RowType).AcceptChanges();

            // Add to the table
            if (state == DataRowState.Added)
            {
                ObservableCollection <DataRow> items = hostListView.ItemsSource as ObservableCollection <DataRow>;

                // -2 because we already added the row to the table. We want the position of the last available
                int newIndex = finalRow.Table.Rows.Count > 1 ?
                               items.IndexOf(finalRow.Table.Rows[finalRow.Table.Rows.Count - 2]) + 1 :
                               minPosition;

                if (newIndex >= 0)
                {
                    // Insert a new row to the items only if a new position has been found
                    items.Insert(newIndex, finalRow);
                    hostListView.SelectedIndex = newIndex;
                    hostListView.ScrollIntoView(finalRow);
                }
            }

            if (finalRow is IPropertyChangeNotifier)
            {
                (finalRow as IPropertyChangeNotifier).OnAllPropertiesChanged();
            }

            dialog.Title = editingDialogTitle;
        }
 /// <summary>
 ///
 /// </summary>
 protected static void Dialog_AppliedChanges <RowType>(FloatingDialog dialog, string editingDialogTitle, ListView hostListView, CancelRoutedEventArgs e)
     where RowType : DataRow
 {
     Dialog_AppliedChanges <RowType>(dialog, editingDialogTitle, hostListView, 0, e);
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="async">When true, runs the specified server method in a seperate thread.</param>
        /// <param name="postApplying">
        ///		If specified, this function is called after applying is complete. It is the
        ///		function's responsibility to call FloatingDialog.EndApplyChanges() in order to complete the apply cycle.
        /// </param>
        protected static void Dialog_ApplyingChanges <TableType, RowType>(TableType sourceTable, FloatingDialog dialog, MethodInfo saveMethod, CancelRoutedEventArgs e, object[] additionalArgs, bool async, Action postApplying)
            where TableType : DataTable, new()
            where RowType : DataRow
        {
            RowType   editVersion = dialog.Content as RowType;
            DataTable changes     = editVersion.Table.GetChanges();

            // No changes were made, skip the apply (but don't cancel)
            if (changes == null)
            {
                e.Skip = true;

                if (postApplying != null)
                {
                    postApplying();
                }
                else
                {
                    dialog.EndApplyChanges(e);
                }

                return;
            }

            // Remember data state
            DataRowState state = changes.Rows[0].RowState;

            // Will store updated data
            TableType savedVersion = null;

            object[] actualArgs = additionalArgs != null? new object[additionalArgs.Length + 1] : new object[1];
            actualArgs[0] = Oltp.Prepare <TableType>(changes);
            if (additionalArgs != null)
            {
                additionalArgs.CopyTo(actualArgs, 1);
            }

            // Save the changes to the DB
            Delegate[] delegates = new Delegate[] {
                (Action) delegate()
                {
                    using (OltpProxy proxy = new OltpProxy())
                    {
                        savedVersion = (TableType)saveMethod.Invoke(proxy.Service, actualArgs);
                    }
                },
                (Func <Exception, bool>) delegate(Exception ex)
                {
                    // Failed, so cancel and display a message
                    MessageBoxError("Error while updating.", ex);
                    e.Cancel = true;
                    return(false);
                },
                (Action) delegate()
                {
                    // Special case when adding a new row
                    if (state == DataRowState.Added)
                    {
                        // Import the saved row
                        sourceTable.ImportRow(savedVersion.Rows[0]);

                        // Even though nothing needs to be updated, mark it as added so AppliedChanges handled treats it properly
                        RowType newRow = sourceTable.Rows[sourceTable.Rows.Count - 1] as RowType;
                        newRow.SetAdded();

                        // Set as new target content
                        dialog.TargetContent = newRow;
                        dialog.Content       = Dialog_MakeEditVersion <TableType, RowType>(sourceTable, newRow);
                    }

                    // Activate the post applying action
                    if (postApplying != null)
                    {
                        postApplying();
                    }
                    else
                    {
                        dialog.EndApplyChanges(e);
                    }
                }
            };

            if (async)
            {
                App.CurrentPage.Window.AsyncOperation(delegates[0] as Action, delegates[1] as Func <Exception, bool>, delegates[2] as Action);
            }
            else
            {
                bool exception = false;
                try { (delegates[0] as Action).Invoke(); }
                catch (Exception ex) { (delegates[1] as Func <Exception, bool>).Invoke(ex); exception = true; }

                if (!exception)
                {
                    (delegates[2] as Action).Invoke();
                }

                if (postApplying != null)
                {
                    postApplying();
                }
                else
                {
                    dialog.EndApplyChanges(e);
                }
            }
        }
 protected static void Dialog_ApplyingChanges <TableType, RowType>(TableType sourceTable, FloatingDialog dialog, MethodInfo saveMethod, CancelRoutedEventArgs e, object[] additionalArgs)
     where TableType : DataTable, new()
     where RowType : DataRow
 {
     Dialog_ApplyingChanges <TableType, RowType>(sourceTable, dialog, saveMethod, e, additionalArgs, false, null);
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="async">When true, runs the specified server method in a seperate thread.</param>
        /// <param name="postApplying">
        ///		If specified, this function is called after applying is complete. It is the
        ///		function's responsibility to call FloatingDialog.EndApplyChanges() in order to complete the apply cycle.
        /// </param>
        protected static void Dialog_ApplyingChanges <TableT, RowT>
        (
            TableT sourceTable,
            FloatingDialog dialog,
            MethodInfo saveMethod,
            CancelRoutedEventArgs e,
            object[] additionalArgs,
            bool async,
            Action postApplying
        )
            where TableT : DataTable, new()
            where RowT : DataRow
        {
            RowT      controlRow = dialog.Content as RowT;
            DataTable changes    = controlRow.Table.GetChanges();

            // No changes were made, skip the apply (but don't cancel)
            if (changes == null)
            {
                e.Skip = true;

                if (postApplying != null)
                {
                    postApplying();
                }
                else
                {
                    dialog.EndApplyChanges(e);
                }

                return;
            }

            if (dialog.IsBatch)
            {
                // Copy all target rows and apply the changed values to them
                TableT clonedTargetTable = new TableT();
                foreach (RowT row in (IEnumerable)dialog.TargetContent)
                {
                    clonedTargetTable.ImportRow(row);
                }
                clonedTargetTable.AcceptChanges();
                dialog.ApplyBindingsToItems(clonedTargetTable.Rows);
                // Get these changes
                changes = clonedTargetTable.GetChanges();
            }

            // No changes were made, skip the apply (but don't cancel)
            if (changes == null)
            {
                e.Skip = true;

                if (postApplying != null)
                {
                    postApplying();
                }
                else
                {
                    dialog.EndApplyChanges(e);
                }

                return;
            }

            // Remember data state
            DataRowState state = controlRow.RowState;

            // Will store updated data
            TableT savedVersion = null;

            // Create a typed version of the changes
            object[] actualArgs = additionalArgs != null? new object[additionalArgs.Length + 1] : new object[1];
            actualArgs[0] = Oltp.Prepare <TableT>(changes);
            if (additionalArgs != null)
            {
                additionalArgs.CopyTo(actualArgs, 1);
            }

            // Save the changes to the DB
            Delegate[] delegates = new Delegate[] {
                (Action) delegate()
                {
                    using (OltpProxy proxy = new OltpProxy())
                    {
                        savedVersion = (TableT)saveMethod.Invoke(proxy.Service, actualArgs);
                    }
                },
                (Func <Exception, bool>) delegate(Exception ex)
                {
                    // Failed, so cancel and display a message
                    MainWindow.MessageBoxError("Error while updating.\n\nChanges may have been saved, if re-saving doesn't work please refresh the page.", ex);
                    e.Cancel = true;
                    return(false);
                },
                (Action) delegate()
                {
                    // Special case when adding a new row
                    if (!dialog.IsBatch && state == DataRowState.Added)
                    {
                        // Import the saved row
                        sourceTable.ImportRow(savedVersion.Rows[0]);

                        // Even though nothing needs to be updated, mark it as added so AppliedChanges handled treats it properly
                        RowT newRow = sourceTable.Rows[sourceTable.Rows.Count - 1] as RowT;
                        newRow.SetAdded();

                        // Set as new target content
                        dialog.TargetContent = newRow;
                        dialog.Content       = Dialog_MakeEditVersion <TableT, RowT>(newRow);
                    }

                    // Activate the post applying action
                    if (postApplying != null)
                    {
                        postApplying();
                    }
                    else
                    {
                        dialog.EndApplyChanges(e);
                    }
                }
            };

            if (async)
            {
                App.CurrentPage.Window.AsyncOperation(
                    delegates[0] as Action,                                     // out-of-ui action
                    delegates[1] as Func <Exception, bool>,                     // exception handler
                    delegates[2] as Action                                      // in-ui action
                    );
            }
            else
            {
                bool exception = false;
                try
                {
                    // out-of-ui action, done in ui because async is not required
                    (delegates[0] as Action).Invoke();
                }
                catch (Exception ex)
                {
                    // exception handler
                    (delegates[1] as Func <Exception, bool>).Invoke(ex);
                    exception = true;
                }

                // in-ui action
                if (!exception)
                {
                    (delegates[2] as Action).Invoke();
                }

                if (postApplying != null)
                {
                    postApplying();
                }
                else
                {
                    dialog.EndApplyChanges(e);
                }
            }
        }
 protected static void Dialog_ApplyingChanges <TableT, RowT>(TableT sourceTable, FloatingDialog dialog, MethodInfo saveMethod, CancelRoutedEventArgs e)
     where TableT : DataTable, new()
     where RowT : DataRow
 {
     Dialog_ApplyingChanges <TableT, RowT>(sourceTable, dialog, saveMethod, e, null, false, null);
 }
Esempio n. 10
0
        /// <summary>
        ///
        /// </summary>
        public void StartApplyChanges(bool closeDialog)
        {
            if (!this.IsOpen)
            {
                throw new InvalidOperationException("Dialog is not open");
            }

            // Update source because the binding might not have been activated, so change focus to trigger it
            this.Focus();

            // Validations
            List <string> errors = new List <string>();

            if (_bindings != null)
            {
                foreach (BEData bdata in _bindings)
                {
                    if (bdata.Exp.HasError)
                    {
                        errors.Add(bdata.Exp.ValidationError.ErrorContent as string);
                    }
                    else if (bdata.Exp.ParentBinding.ValidationRules.Count > 0)
                    {
                        foreach (ValidationRule rule in bdata.Exp.ParentBinding.ValidationRules)
                        {
                            // Validate the binding again (just in case)
                            ValidationResult result = rule.Validate(bdata.Obj.GetValue(bdata.Prp), null);

                            if (!result.IsValid)
                            {
                                errors.Add(result.ErrorContent as string);

                                // Trigger a validation error
                                bdata.Exp.UpdateSource();
                                break;
                            }
                        }
                    }
                }
            }

            // Fail on any validation error
            if (errors.Count > 0)
            {
                string output = string.Empty;
                foreach (string error in errors)
                {
                    if (!string.IsNullOrEmpty(error))
                    {
                        output += error + "\n";
                    }
                }
                MessageBox.Show(output, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            // Raise the before event, this puts the DataRow in edit mode
            CancelRoutedEventArgs bargs = new CancelRoutedEventArgs();

            bargs.RoutedEvent = ApplyingChangesEvent;
            bargs.CloseDialog = closeDialog;
            bargs.Source      = this;

            OnApplyingChanges(bargs);
        }