using System;
using System.Windows;
using System.Linq;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Primitives;
using System.Collections.ObjectModel;
using ProductRiaLib.Web.Services;
using ProductRiaLib.Web.Models;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using ProductApp.Common;
namespace ProductApp.ViewModels
{
[Export(typeof(IModule)), ExportMetadata(MetadataKeys.Name, ModuleID.ProductListViewModel)]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ProductListViewModel : ViewModelBase, IModule
{
private IProductListModel _productListModel;
private Category _comboDefault = new Category { CategoryID = -1, CategoryName = "Please Select" };
public ProductListViewModel()
{
// Inject the Model as the Lazy object with the defined type
_productListModel = ModuleCatalogService.Container.GetExport<IProductListModel>(ModuleID.ProductListModel).Value;
// Register the event handlers defined in the Model
_productListModel.GetCategoryLookupComplete += ProductListModel_GetCategryComplete;
_productListModel.GetCategorizedProductsComplete += ProductListModel_GetCategorizedProductComplete;
_productListModel.SaveChangesComplete += ProductListModel_SaveChangesComplete;
// Register message handler
Messenger.Default.Register(this, MessageToken.DataToProductListVmMessage, new Action<Product>(OnDataToProductListVmMessage));
// Send callback message to retrieve the state info
Messenger.Default.Send(new NotificationMessageAction<StateCacheList<StateCache>>
(ModuleID.ProductListViewModel, OnGetStateMessageCallback),
MessageToken.GetStateMessage);
// Get data for Category dropdown list
_productListModel.GetCategoryLookup();
}
private void OnGetStateMessageCallback(StateCacheList<StateCache> stateList)
{
if (stateList != null)
{
// Re-populate the SelectedCategory prorperty
SelectedCategory = (from w in stateList
where w.MemberName == "SelectedCategory"
select w.MemberValue).FirstOrDefault() as Category;
}
}
private void SaveStateForMe()
{
// Send message for saving state
var stateList = new StateCacheList<StateCache>{
new StateCache { ModuleID = ModuleID.ProductListViewModel,
MemberName = "SelectedCategory",
MemberValue = SelectedCategory,
}
// Other StateCache item can be added here...
};
Messenger.Default.Send(stateList, MessageToken.PutStateMessage);
}
private ObservableCollection<Category> _categoryItems;
//
public ObservableCollection<Category> CategoryItems
{
get { return _categoryItems; }
private set
{
if (!ReferenceEquals(_categoryItems, value))
{
_categoryItems = value;
RaisePropertyChanged("CategoryItems");
}
}
}
private Category _selectedCategory;
//
public Category SelectedCategory
{
get { return _selectedCategory; }
set
{
if (!ReferenceEquals(_selectedCategory, value))
{
_selectedCategory = value;
RaisePropertyChanged("SelectedCategory");
}
}
}
private ObservableCollection<Product> _productItems;
//
public ObservableCollection<Product> ProductItems
{
get { return _productItems; }
private set
{
if (!ReferenceEquals(_productItems, value))
{
_productItems = value;
RaisePropertyChanged("ProductItems");
}
}
}
private Product _currentProduct;
//-->
public Product CurrentProduct
{
get { return _currentProduct; }
set
{
if (!ReferenceEquals(_currentProduct, value))
{
_currentProduct = value;
RaisePropertyChanged("CurrentProduct");
}
}
}
private RelayCommand _categorySelectionChanged;
//
public RelayCommand CategorySelectionChanged
{
get
{
if (_categorySelectionChanged == null)
{
_categorySelectionChanged = new RelayCommand(
OnCategorySelectionChanged,
() => true);
}
return _categorySelectionChanged;
}
}
//
private void OnCategorySelectionChanged()
{
try
{
// Reload the data to context based on the selected category
Category item = SelectedCategory;
if (item != null && item.CategoryID > 0)
{
_productListModel.GetCategorizedProducts((int)item.CategoryID);
}
// Remove the "Please Select"
if (SelectedCategory != _comboDefault)
{
CategoryItems.Remove(_comboDefault);
}
// Enable the Add button
AddProductCommand.RaiseCanExecuteChanged();
}
catch (Exception ex)
{
Messenger.Default.Send(ex, MessageToken.RaiseErrorMessage);
}
}
private RelayCommand _addProductCommand;
//
public RelayCommand AddProductCommand
{
get
{
if (_addProductCommand == null)
{
_addProductCommand = new RelayCommand(
OnAddProductCommand,
() => SelectedCategory != null && SelectedCategory.CategoryID > 0);
}
return _addProductCommand;
}
}
//
private void OnAddProductCommand()
{
Messenger.Default.Send("", MessageToken.LoadAddProductViewMessage);
Messenger.Default.Send(SelectedCategory, MessageToken.DataToAddProductVmMessage);
}
//
private void OnDataToProductListVmMessage(Product addedProduct)
{
try
{
if (!_productListModel.IsBusy && addedProduct != null)
{
// Add to Context in the model
_productListModel.AddNewProduct(addedProduct);
// Add to ObCollection for refreshing display
ProductItems.Add(addedProduct);
}
}
catch (Exception ex)
{
Messenger.Default.Send(ex, MessageToken.RaiseErrorMessage);
}
}
private RelayCommand _saveChangesCommand;
//
public RelayCommand SaveChangesCommand
{
get
{
if (_saveChangesCommand == null)
{
_saveChangesCommand = new RelayCommand(
OnSaveChangesCommand,
() => CurrentProduct != null);
}
return _saveChangesCommand;
}
}
//
private void OnSaveChangesCommand()
{
try
{
if (!_productListModel.IsBusy && _productListModel.HasChanges)
{
_productListModel.SaveChanges(OperationTypes.Update);
SaveChangesCommand.CanExecute(false);
}
}
catch (Exception ex)
{
Messenger.Default.Send(ex, MessageToken.RaiseErrorMessage);
}
}
private RelayCommand _deleteProductCommand;
//
public RelayCommand DeleteProductCommand
{
get
{
if (_deleteProductCommand == null)
{
_deleteProductCommand = new RelayCommand(
OnDeleteProductCommand,
() => CurrentProduct != null);
}
return _deleteProductCommand;
}
}
//
private void OnDeleteProductCommand()
{
try
{
if (!_productListModel.IsBusy && CurrentProduct != null)
{
// Send dialog message with callback from user response
MessageBoxResult theResult = MessageBoxResult.Cancel;
var dialogMessage = new DialogMessage(this,
StaticText.MessageBoxDeleteConfirmation,
rs => theResult = rs)
{
Button = MessageBoxButton.OKCancel,
Caption = StaticText.MessageBoxConfirmationCaption
};
Messenger.Default.Send(dialogMessage, MessageToken.UseDialogMessage);
if (theResult == MessageBoxResult.OK)
{
_productListModel.DeleteProduct(CurrentProduct);
// Remove the item in the display
ProductItems.Remove(CurrentProduct);
}
}
}
catch (Exception ex)
{
Messenger.Default.Send(ex, MessageToken.RaiseErrorMessage);
}
}
private RelayCommand _dataGridSelectionChanged;
//
public RelayCommand DataGridSelectionChanged
{
get
{
if (_dataGridSelectionChanged == null)
{
_dataGridSelectionChanged = new RelayCommand(
OnDataGridSelectionChanged,
() => true);
}
return _dataGridSelectionChanged;
}
}
//
private void OnDataGridSelectionChanged()
{
try
{
// Enable buttons
SaveChangesCommand.RaiseCanExecuteChanged();
DeleteProductCommand.RaiseCanExecuteChanged();
}
catch (Exception ex)
{
Messenger.Default.Send(ex, MessageToken.RaiseErrorMessage);
}
}
private void ProductListModel_GetCategryComplete(object sender, QueryResultsArgs<Category> e)
{
if (!e.HasError)
{
// Set the returned data from async loading to data object
CategoryItems = e.Results;
if (SelectedCategory == null)
{
// Add the combo default item "Please Select"
CategoryItems.Insert(0, _comboDefault);
// Set selected category if not from state cache
SelectedCategory = CategoryItems[0];
}
}
else
{
// Send error message
Messenger.Default.Send(e.Error, MessageToken.RaiseErrorMessage);
}
}
private void ProductListModel_GetCategorizedProductComplete(object sender, QueryResultsArgs<Product> e)
{
if (!e.HasError)
{
ProductItems = e.Results;
}
else
{
// Send error message
Messenger.Default.Send(e.Error, MessageToken.RaiseErrorMessage);
}
}
private void ProductListModel_SaveChangesComplete(object sender, SubmitOperationArgs e)
{
string msgBody = string.Empty;
if (!e.HasError)
{
// Send different messages for particular type of operations
switch (_productListModel.CurrentOperation)
{
case OperationTypes.AddNew:
msgBody = StaticText.MessageBoxAddNewDone;
break;
case OperationTypes.Update:
msgBody = StaticText.MessageBoxSaveChangesDone;
break;
case OperationTypes.Delete:
msgBody = StaticText.MessageBoxDeleteDone;
break;
default:
msgBody = StaticText.MessageBoxSaveChangesDone;
break;
}
var dialogMessage = new DialogMessage(this, msgBody, null)
{
Button = MessageBoxButton.OK,
Caption = StaticText.MessageBoxStatusCaption
};
Messenger.Default.Send(dialogMessage, MessageToken.UseDialogMessage);
}
else
{
// Send error message
Messenger.Default.Send(e.Error, MessageToken.RaiseErrorMessage);
}
}
public override void Cleanup()
{
// Call for saving state info
SaveStateForMe();
if (_productListModel != null)
{
// Unregister all event handling
_productListModel.GetCategoryLookupComplete -= ProductListModel_GetCategryComplete;
_productListModel.GetCategorizedProductsComplete -= ProductListModel_GetCategorizedProductComplete;
_productListModel.SaveChangesComplete -= ProductListModel_SaveChangesComplete;
// No clean-up for shared Model module, just set instance to null
_productListModel = null;
}
// Set data catch for properties to null
_categoryItems = null;
_productItems = null;
_selectedCategory = null;
_currentProduct = null;
_comboDefault = null;
// Unregister any message for this ViewModel
base.Cleanup();
}
}
}