1#if !XAMARIN && !WINDOWS_UWP
10using System.Collections;
11using System.Collections.Generic;
12using System.Collections.ObjectModel;
13using System.ComponentModel;
14using System.Windows.Data;
15using System.Reflection;
18using System.Threading.Tasks;
35 _factoryParameters =
new ObservableCollection<object>();
36 _factoryParameters.CollectionChanged +=
37 new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_factoryParameters_CollectionChanged);
52 protected virtual void OnSaved(
object newObject, Exception error,
object userState)
58 void _factoryParameters_CollectionChanged(
59 object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
66 private Type _objectType =
null;
67 private bool _manageLifetime;
68 private string _factoryMethod =
string.Empty;
69 private ObservableCollection<object> _factoryParameters;
70 private bool _isAsynchronous;
71 private CslaDataProviderCommandManager _commandManager;
83 return _commandManager;
100 OnPropertyChanged(
new PropertyChangedEventArgs(
"ObjectType"));
114 return _manageLifetime;
118 _manageLifetime = value;
119 OnPropertyChanged(
new PropertyChangedEventArgs(
"ManageObjectLifetime"));
123 private object _dataChangedHandler;
138 return _dataChangedHandler;
142 _dataChangedHandler = value;
146 OnPropertyChanged(
new PropertyChangedEventArgs(
"DataChangedHandler"));
160 return _factoryMethod;
164 _factoryMethod = value;
165 OnPropertyChanged(
new PropertyChangedEventArgs(
"FactoryMethod"));
177 return _factoryParameters;
188 get {
return _isAsynchronous; }
189 set { _isAsynchronous = value; }
201 OnQueryFinished(value,
null,
null,
null);
202 OnPropertyChanged(
new PropertyChangedEventArgs(
"ObjectInstance"));
211 get {
return _isBusy; }
215 OnPropertyChanged(
new PropertyChangedEventArgs(
"IsBusy"));
234 private bool _firstRun =
true;
235 private bool _init =
false;
236 private bool _endInitCompete =
false;
237 private bool _endInitError =
false;
255 _endInitCompete =
true;
271 if (!IsInitialLoadEnabled)
281 _endInitError =
false;
282 OnQueryFinished(
null);
286 if (this.IsRefreshDeferred)
289 QueryRequest request =
new QueryRequest();
290 request.ObjectType = _objectType;
291 request.FactoryMethod = _factoryMethod;
292 request.FactoryParameters = _factoryParameters;
293 request.ManageObjectLifetime = _manageLifetime;
298 System.Threading.ThreadPool.QueueUserWorkItem(DoQuery, request);
311 T result =
default(T);
312 Exception exceptionResult =
null;
321 exceptionResult = ex.BusinessException;
323 catch (System.Reflection.TargetInvocationException ex)
325 if (ex.InnerException !=
null)
327 exceptionResult = ex.InnerException;
329 if (dpe !=
null && dpe.BusinessException !=
null)
333 exceptionResult = ex;
337 exceptionResult = ex;
347 if (!_endInitCompete && exceptionResult !=
null)
348 _endInitError =
true;
351 OnQueryFinished(result, exceptionResult, (o) => {
IsBusy =
false;
return null; },
null);
363 T result =
default(T);
364 Exception exceptionResult =
null;
369 result = await factory();
373 exceptionResult = ex.BusinessException;
375 catch (System.Reflection.TargetInvocationException ex)
377 if (ex.InnerException !=
null)
379 exceptionResult = ex.InnerException;
381 if (dpe !=
null && dpe.BusinessException !=
null)
385 exceptionResult = ex;
389 exceptionResult = ex;
399 if (!_endInitCompete && exceptionResult !=
null)
400 _endInitError =
true;
403 OnQueryFinished(result, exceptionResult, (o) => {
IsBusy =
false;
return null; },
null);
406 private void DoQuery(
object state)
408 QueryRequest request = (QueryRequest)state;
409 object result =
null;
410 Exception exceptionResult =
null;
411 object[] parameters =
new List<object>(request.FactoryParameters).ToArray();
416 BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy;
417 System.Reflection.MethodInfo factory = request.ObjectType.GetMethod(
418 request.FactoryMethod, flags,
null,
419 MethodCaller.GetParameterTypes(parameters),
null);
426 int parameterCount = parameters.Length;
427 System.Reflection.MethodInfo[] methods = request.ObjectType.GetMethods(flags);
428 foreach (System.Reflection.MethodInfo method in methods)
429 if (method.Name == request.FactoryMethod && method.GetParameters().Length == parameterCount)
440 throw new InvalidOperationException(
447 result = factory.Invoke(
null, parameters);
451 exceptionResult = ex.BusinessException;
453 catch (System.Reflection.TargetInvocationException ex)
455 if (ex.InnerException !=
null)
457 exceptionResult = ex.InnerException;
459 if (dpe !=
null && dpe.BusinessException !=
null)
463 exceptionResult = ex;
467 exceptionResult = ex;
472 exceptionResult = ex;
475 if (request.ManageObjectLifetime && result !=
null)
482 if (!_endInitCompete && exceptionResult !=
null)
483 _endInitError =
true;
486 OnQueryFinished(result, exceptionResult, (o) => {
IsBusy =
false;
return null; },
null);
490 #region QueryRequest Class
492 private class QueryRequest
494 private Type _objectType;
498 get {
return _objectType; }
499 set { _objectType = value; }
502 public Func<object[], Task<object>> Factory {
get;
set; }
504 private string _factoryMethod;
508 get {
return _factoryMethod; }
509 set { _factoryMethod = value; }
512 private ObservableCollection<object> _factoryParameters;
516 get {
return _factoryParameters; }
517 set { _factoryParameters =
518 new ObservableCollection<object>(
new List<object>(value)); }
520 private bool _manageLifetime;
524 get {
return _manageLifetime; }
525 set { _manageLifetime = value; }
534#region Cancel/Update/New/Remove
547 if (undo !=
null && _manageLifetime)
583 object result = savable;
584 Exception exceptionResult =
null;
590 ICloneable clonable = savable as ICloneable;
591 if (clonable !=
null)
596 if (undo !=
null && _manageLifetime)
601 result = savable.Save();
606 Core.ISavable original = this.Data as Core.ISavable;
607 if (original !=
null)
608 original.SaveComplete(result);
613 if (undo !=
null && _manageLifetime)
618 exceptionResult = ex;
621 OnQueryFinished(
null, exceptionResult,
null,
null);
623 OnQueryFinished(result,
null,
null,
null);
625 OnSaved(result, exceptionResult,
null);
638 IBindingList list = this.Data as IBindingList;
639 if (list !=
null && list.AllowNew)
640 return list.AddNew();
663 list = bb.
Parent as IBindingList;
665 list = this.Data as IBindingList;
666 if (list !=
null && list.AllowRemove)
Provides consistent context information between the client and server DataPortal objects.
static bool AutoCloneOnUpdate
Gets a value indicating whether objects should be automatically cloned by the data portal Update() me...
This is the non-generic base class from which most business objects will be derived.
Core.IParent Parent
Provide access to the parent reference for use in child object code.
Event arguments containing a reference to the new object that was returned as a result of the Save() ...
This exception is returned for any errors occurring during the server-side DataPortal invocation.
Exception BusinessException
Gets the original server-side exception.
A strongly-typed resource class, for looking up localized strings, etc.
static string NoSuchFactoryMethod
Looks up a localized string similar to No such factory method:{0}.
Implements support for RoutedCommands that can be executed by the CslaDataProvider control.
Wraps and creates a CSLA .NET-style object that you can use as a binding source.
void Refresh< T >(Func< T > factory)
Refresh the ObjectInstance by calling the supplied factory.
object AddNew()
Adds a new item to the object if the object implements IBindingList and AllowNew is true.
override void BeginQuery()
Overridden.
object ObjectInstance
Gets or sets a reference to the data object.
bool ManageObjectLifetime
Gets or sets a value indicating whether the data control should manage the lifetime of the business o...
bool IsAsynchronous
Gets or sets a value that indicates whether to perform object creation in a worker thread or in the a...
void Rebind()
Triggers WPF data binding to rebind to the data object.
IList FactoryParameters
Get the list of parameters to pass to the factory method.
override void BeginInit()
Indicates that the control is about to initialize.
Type ObjectType
Gets or sets the type of object to create an instance of.
string FactoryMethod
Gets or sets the name of the static (Shared in Visual Basic) factory method that should be called to ...
CslaDataProviderCommandManager CommandManager
Gets an object that can be used to execute Save and Undo commands on this CslaDataProvider through XA...
void Cancel()
Cancels changes to the business object, returning it to its previous state.
virtual void OnSaved(object newObject, Exception error, object userState)
Raise the Saved event when the object has been saved.
override void EndInit()
Indicates that the control has initialized.
CslaDataProvider()
Creates an instance of the object.
void RemoveItem(object sender, ExecuteEventArgs e)
Removes an item from the list if the object implements IBindingList and AllowRemove is true.
object DataChangedHandler
Gets or sets a reference to an object that will handle the DataChanged event raised by this data prov...
void Save()
Accepts changes to the business object, and commits them by calling the object's Save() method.
EventHandler< Csla.Core.SavedEventArgs > Saved
Event raised when the object has been saved.
bool IsBusy
Gets a value indicating if this object is busy.
Arguments passed to a method invoked by the Execute trigger action.
Specifies that the object can save itself.
Define the common methods used by the UI to interact with n-level undo.
void ApplyEdit()
Commits the current edit process.
void BeginEdit()
Starts a nested edit on the object.
Interface defining the interaction between a CslaDataSource and an error dialog control.
void Register(object source)
Method called by the CslaDataProvider when the error dialog should register any events it wishes to h...