PageRenderTime 33ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/Coding4Fun.CurrencyExchange/ViewModels/MainViewModel.cs

#
C# | 394 lines | 327 code | 67 blank | 0 comment | 36 complexity | 6c48dbef3cca69d848e9cf41ce90d9b4 MD5 | raw file
  1. using System;
  2. using System.ComponentModel;
  3. using System.Linq;
  4. using System.Runtime.Serialization;
  5. using System.Windows;
  6. using Coding4Fun.CurrencyExchange.Helpers;
  7. using Coding4Fun.CurrencyExchange.Models;
  8. namespace Coding4Fun.CurrencyExchange.ViewModels
  9. {
  10. public class MainViewModel : INotifyPropertyChanged
  11. {
  12. private const string SettingFileName = "mainviewmodel.dat";
  13. private ICurrencyExchangeService _currencyExchangeService;
  14. private string _busyMessage = null;
  15. private double _amount;
  16. private ICurrency _fromCurrency;
  17. private ICurrency _toCurrency;
  18. private ICurrencyExchangeResult _result;
  19. #region Properties
  20. [IgnoreDataMember]
  21. public static MainViewModel Instance { get; protected set; }
  22. [IgnoreDataMember]
  23. public ICurrencyExchangeService CurrencyExchangeService
  24. {
  25. get
  26. {
  27. return _currencyExchangeService;
  28. }
  29. set
  30. {
  31. if (_currencyExchangeService == value)
  32. return;
  33. _currencyExchangeService = value;
  34. _fromCurrency = Currencies.FirstOrDefault(x => x.Name == "US Dollar") ?? Currencies[0];
  35. _toCurrency = Currencies.FirstOrDefault(x => x.Name == "Euro") ?? Currencies[1];
  36. RaisePropertyChanged("CurrencyExchangeService");
  37. RaisePropertyChanged("Currencies");
  38. }
  39. }
  40. [IgnoreDataMember]
  41. public ICurrency[] Currencies
  42. {
  43. get
  44. {
  45. return _currencyExchangeService.Currencies;
  46. }
  47. }
  48. [DataMember]
  49. public string Amount
  50. {
  51. get
  52. {
  53. return _amount.ToString("0.00");
  54. }
  55. set
  56. {
  57. double amount;
  58. if (double.TryParse(value, out amount))
  59. {
  60. if (_amount == amount)
  61. return;
  62. _amount = amount;
  63. RaisePropertyChanged("Amount");
  64. }
  65. else
  66. throw new Exception("Please enter a valid Amount");
  67. }
  68. }
  69. [IgnoreDataMember]
  70. public ICurrency FromCurrency
  71. {
  72. get
  73. {
  74. return _fromCurrency;
  75. }
  76. set
  77. {
  78. if (_fromCurrency == value)
  79. return;
  80. _fromCurrency = value;
  81. RaisePropertyChanged("FromCurrency");
  82. }
  83. }
  84. [IgnoreDataMember]
  85. public ICurrency ToCurrency
  86. {
  87. get
  88. {
  89. return _toCurrency;
  90. }
  91. set
  92. {
  93. if (_toCurrency == value)
  94. return;
  95. _toCurrency = value;
  96. RaisePropertyChanged("ToCurrency");
  97. }
  98. }
  99. [IgnoreDataMember]
  100. public ICurrencyExchangeResult Result
  101. {
  102. get
  103. {
  104. return _result;
  105. }
  106. protected set
  107. {
  108. if (_result == value)
  109. return;
  110. _result = value;
  111. RaisePropertyChanged("Result");
  112. RaisePropertyChanged("ExchangedCurrency");
  113. RaisePropertyChanged("ExchangedAmount");
  114. RaisePropertyChanged("ExchangedTimeStamp");
  115. }
  116. }
  117. [IgnoreDataMember]
  118. public string ExchangedCurrency
  119. {
  120. get
  121. {
  122. if (_result == null || _result.ExchangedCurrency == null)
  123. return string.Empty;
  124. return _result.ExchangedCurrency.Name;
  125. }
  126. }
  127. [IgnoreDataMember]
  128. public string ExchangedAmount
  129. {
  130. get
  131. {
  132. if (_result == null)
  133. return string.Empty;
  134. return _result.ExchangedAmount.ToString("N2");
  135. }
  136. }
  137. [IgnoreDataMember]
  138. public string ExchangedTimeStamp
  139. {
  140. get
  141. {
  142. if (_result == null)
  143. return string.Empty;
  144. return string.Format("Data freshness:\n{0} at {1}",
  145. _result.Timestamp.ToShortDateString(),
  146. _result.Timestamp.ToShortTimeString());
  147. }
  148. }
  149. [DataMember]
  150. public int FromCurrencyIndex
  151. {
  152. get
  153. {
  154. return Array.IndexOf(Currencies, FromCurrency);
  155. }
  156. set
  157. {
  158. FromCurrency = Currencies[value];
  159. }
  160. }
  161. [DataMember]
  162. public int ToCurrencyIndex
  163. {
  164. get
  165. {
  166. return Array.IndexOf(Currencies, ToCurrency);
  167. }
  168. set
  169. {
  170. ToCurrency = Currencies[value];
  171. }
  172. }
  173. [DataMember]
  174. public CurrencyCachedExchangeRate[] CurrenciesCachedExchangeRates
  175. {
  176. get
  177. {
  178. return Currencies
  179. .Select(x => new CurrencyCachedExchangeRate()
  180. {
  181. CurrencyIndex = Array.IndexOf(Currencies, x),
  182. CachedExchangeRate = x.CachedExchangeRate,
  183. CachedExchangeRateUpdatedOn = x.CachedExchangeRateUpdatedOn
  184. })
  185. .ToArray();
  186. }
  187. set
  188. {
  189. foreach (var currencyData in value)
  190. {
  191. if (currencyData.CurrencyIndex >= Currencies.Length)
  192. continue;
  193. var currency = Currencies[currencyData.CurrencyIndex];
  194. currency.CachedExchangeRate = currencyData.CachedExchangeRate;
  195. currency.CachedExchangeRateUpdatedOn = currencyData.CachedExchangeRateUpdatedOn;
  196. }
  197. }
  198. }
  199. [IgnoreDataMember]
  200. public bool Busy
  201. {
  202. get
  203. {
  204. return !string.IsNullOrEmpty(BusyMessage);
  205. }
  206. }
  207. [IgnoreDataMember]
  208. public string BusyMessage
  209. {
  210. get
  211. {
  212. return _busyMessage;
  213. }
  214. set
  215. {
  216. if (_busyMessage == value)
  217. return;
  218. _busyMessage = value;
  219. RaisePropertyChanged("BusyMessage");
  220. RaisePropertyChanged("BusyVisibility");
  221. }
  222. }
  223. [IgnoreDataMember]
  224. public Visibility BusyVisibility
  225. {
  226. get
  227. {
  228. return Busy ? Visibility.Visible : Visibility.Collapsed;
  229. }
  230. }
  231. #endregion
  232. public MainViewModel()
  233. {
  234. CurrencyExchangeService = new MsnMoneyV2CurrencyExchangeService();
  235. Amount = "100";
  236. }
  237. static MainViewModel()
  238. {
  239. Instance = Load();
  240. }
  241. public void ExchangeCurrency()
  242. {
  243. if (Busy)
  244. return;
  245. BusyMessage = "Exchanging amount...";
  246. _currencyExchangeService.ExchangeCurrency(_amount, _fromCurrency, _toCurrency, true, CurrencyExchanged, null);
  247. }
  248. public void SwapCurrencies()
  249. {
  250. if (Busy)
  251. return;
  252. var tempCurrency = FromCurrency;
  253. FromCurrency = ToCurrency;
  254. ToCurrency = tempCurrency;
  255. }
  256. public void UpdateCachedExchangeRates()
  257. {
  258. if (Busy)
  259. return;
  260. BusyMessage = "Updating cached exchange rates...";
  261. _currencyExchangeService.UpdateCachedExchangeRates(ExchangeRatesUpdated, null);
  262. }
  263. public static MainViewModel Load()
  264. {
  265. return StorageHelper.LoadContract<MainViewModel>(SettingFileName, true);
  266. }
  267. public void Save()
  268. {
  269. StorageHelper.SaveContract(SettingFileName, this, true);
  270. }
  271. private void CurrencyExchanged(ICurrencyExchangeResult result)
  272. {
  273. InvokeOnUiThread(() =>
  274. {
  275. Result = result;
  276. BusyMessage = null;
  277. if (result.Error != null)
  278. {
  279. if (System.Diagnostics.Debugger.IsAttached)
  280. System.Diagnostics.Debugger.Break();
  281. else
  282. MessageBox.Show("An error has ocorred!", "Error", MessageBoxButton.OK);
  283. }
  284. });
  285. }
  286. private void ExchangeRatesUpdated(ICachedExchangeRatesUpdateResult result)
  287. {
  288. InvokeOnUiThread(() =>
  289. {
  290. BusyMessage = null;
  291. Save();
  292. if (result.Error != null)
  293. {
  294. if (System.Diagnostics.Debugger.IsAttached)
  295. System.Diagnostics.Debugger.Break();
  296. else
  297. MessageBox.Show("An error has ocorred!", "Error", MessageBoxButton.OK);
  298. }
  299. });
  300. }
  301. private void InvokeOnUiThread(Action action)
  302. {
  303. var dispatcher = System.Windows.Deployment.Current.Dispatcher;
  304. if (dispatcher.CheckAccess())
  305. action();
  306. else
  307. dispatcher.BeginInvoke(action);
  308. }
  309. public event PropertyChangedEventHandler PropertyChanged;
  310. private void RaisePropertyChanged(string propertyName)
  311. {
  312. if (PropertyChanged != null)
  313. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  314. }
  315. #region Auxiliary Classes
  316. public class CurrencyCachedExchangeRate
  317. {
  318. [DataMember]
  319. public int CurrencyIndex { get; set; }
  320. [DataMember]
  321. public double CachedExchangeRate { get; set; }
  322. [DataMember]
  323. public DateTime CachedExchangeRateUpdatedOn { get; set; }
  324. }
  325. #endregion
  326. }
  327. }