diff options
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DB/ViewModels/DbTableViewModel.cs')
| -rw-r--r-- | Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DB/ViewModels/DbTableViewModel.cs | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DB/ViewModels/DbTableViewModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DB/ViewModels/DbTableViewModel.cs new file mode 100644 index 000000000..b6d77748e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.DB/ViewModels/DbTableViewModel.cs @@ -0,0 +1,320 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.DAL.Observables; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.DB.Managers; +using Tango.SharedUI; +using Tango.MachineStudio.DB.ExtensionMethods; +using System.Data.Entity.Infrastructure; +using GalaSoft.MvvmLight.Messaging; +using Tango.MachineStudio.DB.Messages; +using System.Collections.ObjectModel; +using System.Reflection; +using Tango.MachineStudio.Common.StudioApplication; +using System.ComponentModel; + +namespace Tango.MachineStudio.DB.ViewModels +{ + public abstract class DbTableViewModel<T> : ViewModel, IShutdownRequestBlocker where T : class, IObservableEntity + { + private INotificationProvider _notification; + + /// <summary> + /// Initializes a new instance of the <see cref="DbTableViewModel"/> class. + /// </summary> + public DbTableViewModel(INotificationProvider notification) : base() + { + _notification = notification; + Adapter = ObservablesEntitiesAdapter.Instance; + ValidationErrors = new ObservableCollection<string>(); + + AddCommand = new RelayCommand(OnAdd); + EditCommand = new RelayCommand(OnEdit, (x) => SelectedEntity != null); + DeleteCommand = new RelayCommand(OnDelete, (x) => SelectedEntity != null); + DialogOKCommand = new RelayCommand(() => OnDialogOKPressed(DialogOpenMode, EditEntity)); + DialogCancelCommand = new RelayCommand(() => OnDialogCancelPressed(DialogOpenMode, EditEntity)); + + IsDialogOpen = false; + } + + private T _editEntity; + /// <summary> + /// Gets or sets the edit entity. + /// </summary> + public T EditEntity + { + get { return _editEntity; } + set { _editEntity = value; RaisePropertyChangedAuto(); } + } + + private DialogOpenMode _dialogOpenMode; + /// <summary> + /// Gets or sets the dialog open mode. + /// </summary> + public DialogOpenMode DialogOpenMode + { + get { return _dialogOpenMode; } + set { _dialogOpenMode = value; RaisePropertyChangedAuto(); } + } + + private bool _isDialogOpen; + /// <summary> + /// Gets or sets a value indicating whether this instance is dialog open. + /// </summary> + public bool IsDialogOpen + { + get { return _isDialogOpen; } + set { _isDialogOpen = value; RaisePropertyChangedAuto(); } + } + + private ObservablesEntitiesAdapter _adapter; + /// <summary> + /// Gets or sets the DB adapter. + /// </summary> + public ObservablesEntitiesAdapter Adapter + { + get { return _adapter; } + set { _adapter = value; RaisePropertyChangedAuto(); } + } + + private T _selectedEntity; + /// <summary> + /// Gets or sets the selected entity. + /// </summary> + public T SelectedEntity + { + get { return _selectedEntity; } + set { _selectedEntity = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _filter; + /// <summary> + /// Gets or sets the search filter. + /// </summary> + public String Filter + { + get { return _filter; } + set { _filter = value; RaisePropertyChangedAuto(); OnFilterChanged(value); } + } + + private ObservableCollection<String> _validationErrors; + /// <summary> + /// Gets or sets the validation errors. + /// </summary> + public ObservableCollection<String> ValidationErrors + { + get { return _validationErrors; } + set { _validationErrors = value; RaisePropertyChangedAuto(); } + } + + /// <summary> + /// Gets or sets the dialog OK command. + /// </summary> + public RelayCommand DialogOKCommand { get; set; } + + /// <summary> + /// Gets or sets the dialog cancel command. + /// </summary> + public RelayCommand DialogCancelCommand { get; set; } + + /// <summary> + /// Gets or sets the add command. + /// </summary> + public RelayCommand AddCommand { get; set; } + + /// <summary> + /// Gets or sets the edit command. + /// </summary> + public RelayCommand EditCommand { get; set; } + + /// <summary> + /// Gets or sets the delete command. + /// </summary> + public RelayCommand DeleteCommand { get; set; } + + protected override void OnValidating() + { + base.OnValidating(); + ValidationErrors.Clear(); + + foreach (var prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => !x.PropertyType.IsGenericType && x.PropertyType.IsClass && !x.Name.Contains("Guid"))) + { + if (prop.GetValue(EditEntity) == null) + { + ValidationErrors.Add(prop.Name + " is required"); + } + } + } + + /// <summary> + /// Called when delete command invoked. + /// </summary> + protected virtual async void OnDelete() + { + using (_notification.PushTaskItem("Saving changes to database...")) + { + var dependenctEntities = SelectedEntity.GetDependentEntitiesNameAndGuid(); + + if (dependenctEntities.Count > 0) + { + _notification.ShowError("The selected entity is being used by " + dependenctEntities.Count + " other entities." + Environment.NewLine + "Please delete any dependencies and try again." + Environment.NewLine + Environment.NewLine + String.Join(Environment.NewLine,dependenctEntities.Select(x => x.Key + ", ID: " + x.Value))); + return; + } + + try + { + SelectedEntity.Deleted = true; + await SelectedEntity.SaveAsync(); + } + catch (Exception ex) + { + SelectedEntity.Deleted = false; + Adapter.Invalidate(); + _notification.ShowError("Could not delete entity."); + } + + SelectedEntity = null; + } + } + + /// <summary> + /// Called when edit command invoked. + /// </summary> + protected virtual void OnEdit() + { + ValidationErrors.Clear(); + DialogOpenMode = DialogOpenMode.Editing; + EditEntity = GetEditableEntity(DialogOpenMode); + //_notification.ShowDialog(DialogOpenMode, this); + Messenger.Default.Send(new OpenEntityEditViewMessage(DialogOpenMode, this, typeof(T))); + IsDialogOpen = true; + } + + /// <summary> + /// Called when add command invoked. + /// </summary> + protected virtual void OnAdd() + { + ValidationErrors.Clear(); + DialogOpenMode = DialogOpenMode.Adding; + EditEntity = GetEditableEntity(DialogOpenMode); + //_notification.ShowDialog(DialogOpenMode, this); + Messenger.Default.Send(new OpenEntityEditViewMessage(DialogOpenMode, this, typeof(T))); + IsDialogOpen = true; + } + + /// <summary> + /// Called when dialog closes with OK button. + /// </summary> + /// <param name="mode">The mode.</param> + protected virtual async void OnDialogOKPressed(DialogOpenMode mode, T entity) + { + if (!Validate()) return; + + if (ValidationErrors.Count > 0) return; + + Messenger.Default.Send(new CloseEntityEditViewMessage()); + + if (mode == DialogOpenMode.Editing) + { + entity.ShallowCopyTo(SelectedEntity); + entity = SelectedEntity; + } + + OnBeforeEntitySave(mode, entity); + + using (_notification.PushTaskItem("Saving changes to database...")) + { + try + { + await entity.SaveAsync(); + } + catch (DbUpdateException ex) + { + Adapter.Invalidate(); + _notification.ShowError("Could not save entity." + Environment.NewLine + ex.InnerException.InnerException != null ? ex.InnerException.InnerException.Message : ex.InnerException.Message); + } + catch (Exception ex) + { + Adapter.Invalidate(); + _notification.ShowError("Could not save entity." + Environment.NewLine + "Please make sure all fields are properly populated."); + } + IsDialogOpen = false; + SelectedEntity = EditEntity; + SelectedEntity = null; + } + } + + /// <summary> + /// Called when [before entity save]. + /// </summary> + /// <param name="mode">The mode.</param> + /// <param name="entity">The entity.</param> + protected virtual void OnBeforeEntitySave(DialogOpenMode mode, T entity) + { + + } + + /// <summary> + /// Called when dialog closes with cancel button. + /// </summary> + /// <param name="mode">The mode.</param> + protected virtual void OnDialogCancelPressed(DialogOpenMode mode, T entity) + { + Messenger.Default.Send(new CloseEntityEditViewMessage()); + IsDialogOpen = false; + } + + /// <summary> + /// Gets the editable entity. + /// </summary> + /// <param name="mode">The mode.</param> + /// <returns></returns> + private T GetEditableEntity(DialogOpenMode mode) + { + if (mode == DialogOpenMode.Adding) + { + var newEntity = Activator.CreateInstance<T>(); + InitializeEntity(newEntity); + return newEntity; + } + else + { + return SelectedEntity.ShallowClone(); + } + } + + protected virtual void OnFilterChanged(String filter) + { + String viewSourceName = this.GetType().Name.Replace("ViewVM", "ViewSource"); + ICollectionView collectionView = Adapter.GetType().GetProperty(viewSourceName).GetValue(Adapter) as ICollectionView; + + collectionView.Filter = (entity) => + { + return + entity. + GetType(). + GetProperties(BindingFlags.Public | BindingFlags.Instance). + Where(x => x.Name != "Deleted" && x.Name != "ID" && x.Name != "LastUpdated"). + Where(x => !x.PropertyType.IsGenericType && (x.PropertyType.IsClass || x.PropertyType == typeof(String))). + Select(prop => prop.GetValue(entity).ToString()). + ToList(). + Any(x => x.ToLower().Contains(filter.ToLower())); + }; + } + + protected virtual void InitializeEntity(T entity) + { + + } + + public Task<bool> OnShutdownRequest() + { + return Task.FromResult(true); + } + } +} |
