/// <summary>
        /// Saves the specified item in the list.
        /// </summary>
        /// <param name="index">Index of item to be saved.</param>
        /// <param name="delete">true if the item should be deleted.</param>
        protected virtual async Task SaveItemAsync(int index, bool delete)
        {
            T   item       = this[index];
            var handleBusy = false;

            if ((item.IsDeleted || delete) || (item.IsValid && item.IsDirty))
            {
                T savable = item;

                // attempt to clone object
                ICloneable cloneable = savable as ICloneable;
                if (cloneable != null)
                {
                    savable = (T)cloneable.Clone();
                    MethodCaller.CallMethodIfImplemented(item, "MarkBusy");
                    handleBusy = true;
                }

                // commit all changes
                int editLevel = savable.EditLevel;
                for (int tmp = 1; tmp <= editLevel; tmp++)
                {
                    savable.AcceptChanges(editLevel - tmp, false);
                }

                if (delete)
                {
                    savable.Delete();
                }

                Exception error  = null;
                T         result = default(T);
                var       dp     = ApplicationContext.CreateInstance <DataPortal <T> >();
                try
                {
                    result = await dp.UpdateAsync((T)savable);
                }
                catch (AggregateException ex)
                {
                    if (ex.InnerExceptions.Count > 0)
                    {
                        error = ex.InnerExceptions[0];
                    }
                    else
                    {
                        error = ex;
                    }
                }
                catch (Exception ex)
                {
                    error = ex;
                }
                finally
                {
                    if (handleBusy)
                    {
                        MethodCaller.CallMethodIfImplemented(item, "MarkIdle");
                    }
                }
                // update index - this may have changed under the duration of async call
                index = IndexOf(item);
                if (error == null && result != null)
                {
                    if (savable.IsDeleted)
                    {
                        //SafeRemoveItem  will raise INotifyCollectionChanged event
                        SafeRemoveItem(index);
                    }
                    else
                    {
                        for (int tmp = 1; tmp <= editLevel; tmp++)
                        {
                            result.CopyState(tmp, false);
                        }

                        SafeSetItem(index, result);
                        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
                        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, this[index], index));
                    }
                    item.SaveComplete(result);
                    OnSaved(result, null);
                }
                else
                {
                    item.SaveComplete(item);
                    OnSaved(item, error);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Saves the specified item in the list.
        /// </summary>
        /// <param name="index">
        /// Index of the item to be saved.
        /// </param>
        /// <remarks>
        /// This method properly saves the child item,
        /// by making sure the item in the collection
        /// is properly replaced by the result of the
        /// Save() method call.
        /// </remarks>
        public virtual void SaveItem(int index)
        {
            T   item       = this[index];
            var handleBusy = false;

            if (item.IsDeleted || (item.IsValid && item.IsDirty))
            {
                T savable = item;

                // attempt to clone object
                ICloneable cloneable = savable as ICloneable;
                if (cloneable != null)
                {
                    savable = (T)cloneable.Clone();
                    MethodCaller.CallMethodIfImplemented(item, "MarkBusy");
                    handleBusy = true;
                }

                // commit all changes
                int editLevel = savable.EditLevel;
                for (int tmp = 1; tmp <= editLevel; tmp++)
                {
                    savable.AcceptChanges(editLevel - tmp, false);
                }

                // save object
                DataPortal <T> dp = new DataPortal <T>();
                dp.UpdateCompleted += (o, e) =>
                {
                    if (handleBusy)
                    {
                        MethodCaller.CallMethodIfImplemented(item, "MarkIdle");
                    }
                    if (e.Error == null)
                    {
                        T result = e.Object;
                        if (item.IsDeleted)
                        {
                            //SafeRemoveItem  will raise INotifyCollectionChanged event
                            SafeRemoveItem(index);
                        }
                        else
                        {
                            for (int tmp = 1; tmp <= editLevel; tmp++)
                            {
                                result.CopyState(tmp, false);
                            }

                            SafeSetItem(index, result);
#if SILVERLIGHT
                            //Because SL Data Grid does not support replace action.
                            // we have to artificially raise remove/insert events
                            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
                            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, this[index], index));
#else
                            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, result, item));
#endif
                        }
#if SILVERLIGHT
                        item.SaveComplete(result, null, null);
#else
                        item.SaveComplete(result);
#endif
                        OnSaved(result, null);
                    }
                    else
                    {
#if SILVERLIGHT
                        item.SaveComplete(item, e.Error, null);
#else
                        item.SaveComplete(item);
#endif
                        OnSaved(item, e.Error);
                    }
                };
                dp.BeginUpdate(savable);
            }
        }