BaseVm.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using DevExpress.Utils.MVVM;
  7. using DevExpress.Mvvm.POCO;
  8. using DevExpress.Mvvm;
  9. using DevExpress.XtraSplashScreen;
  10. using DevExpress.XtraBars.Alerter;
  11. using DevExpress.XtraBars.ToastNotifications;
  12. using System.Windows.Forms;
  13. using DevExpress.XtraWaitForm;
  14. using System.Threading;
  15. using DevExpress.XtraEditors;
  16. using DevExpress.Utils.MVVM.Services;
  17. /// <summary>
  18. /// <para>ViewModel基类</para>
  19. /// <para>GetService方法不是线程安全的,避免后台线程调用,可使用BeginInvoke切换到UI线程</para>
  20. /// </summary>
  21. public abstract class BaseVm
  22. {
  23. /// <summary>
  24. /// 切换到UI线程直接委托
  25. /// </summary>
  26. /// <param name="action">UI线程要执行的委托</param>
  27. public void Invoke(Action action)
  28. {
  29. try
  30. {
  31. IDispatchService.Invoke(action);
  32. }
  33. catch (Exception)
  34. {
  35. //退出时这里可能会出错,此时可忽略
  36. }
  37. }
  38. /// <summary>
  39. /// 切换到UI线程直接委托
  40. /// </summary>
  41. /// <param name="action">UI线程要执行的委托</param>
  42. public async void BeginInvoke(Action action)
  43. {
  44. await IDispatchService.BeginInvoke(action);
  45. }
  46. /// <summary>
  47. /// 向其它ViewModel发送数据
  48. /// </summary>
  49. /// <typeparam name="T">数据泛型类型,需要和Register中的类型一致</typeparam>
  50. /// <param name="data">数据</param>
  51. /// <param name="token">令牌,需要和Register中的令牌一致</param>
  52. public void Send<T>(T data, string token)
  53. {
  54. DevExpress.Mvvm.Messenger.Default.Send(data, token);
  55. }
  56. /// <summary>
  57. /// <para>注册接收其它ViewModel数据的回调</para>
  58. /// <para>需要注意callback执行线程可能不是UI线程,callback操作绑定对象需要调用Invoke或BeginInvoke</para>
  59. /// </summary>
  60. /// <typeparam name="T">数据泛型类型,需要和Send中的类型一致</typeparam>
  61. /// <param name="callback">数据</param>
  62. /// <param name="token">令牌,需要和Send中的令牌一致</param>
  63. public void Register<T>(Action<T> callback, string token)
  64. {
  65. DevExpress.Mvvm.Messenger.Default.Register(this, token, callback);
  66. }
  67. protected DialogResult DialogResult;
  68. public void UnRegister()
  69. {
  70. DevExpress.Mvvm.Messenger.Default.Unregister(this);
  71. }
  72. /// <summary>
  73. /// 选择目录(取消则返回null)
  74. /// </summary>
  75. /// <returns></returns>
  76. public string DialogChooseDir()
  77. {
  78. if (!IFolderService.ShowDialog()) return null;
  79. return IFolderService.ResultPath;
  80. }
  81. /// <summary>
  82. /// 选择文件(取消则返回null)
  83. /// </summary>
  84. /// <param name="filter">such as "文本文件|*.txt"</param>
  85. /// <param name="multiselect">是否支持多选</param>
  86. /// <returns></returns>
  87. public string DialogChooseFile(string filter = "文本文件|*.txt", bool multiselect = false)
  88. {
  89. IOpenFileService.Filter = filter;
  90. IOpenFileService.Multiselect = multiselect;
  91. if (!IOpenFileService.ShowDialog()) return null;
  92. return IOpenFileService.GetFullFileName();
  93. }
  94. /// <summary>
  95. /// 保存文件(取消则返回null)
  96. /// </summary>
  97. /// <param name="fileName"></param>
  98. /// <returns></returns>
  99. public string DialogSaveFile(string fileName)
  100. {
  101. if (!ISaveFileService.ShowDialog(null, "", fileName)) return null;
  102. return ISaveFileService.GetFullFileName();
  103. }
  104. /// <summary>
  105. /// 从右下角弹出通知
  106. /// </summary>
  107. /// <param name="msg"></param>
  108. public void ShowNotify(string msg)
  109. {
  110. Invoke(async () =>
  111. {
  112. var notify = INotifyService.CreatePredefinedNotification("消息", "\r\n" + " " + msg, null);
  113. await notify.ShowAsync();
  114. });
  115. }
  116. /// <summary>
  117. /// 从右下角弹出通知
  118. /// </summary>
  119. /// <param name="msg"></param>
  120. public void ShowNotifyError(string msg)
  121. {
  122. Invoke(async () =>
  123. {
  124. var notify = INotifyService.CreatePredefinedNotification("错误", "\r\n" + " " + msg, null);
  125. await notify.ShowAsync();
  126. });
  127. }
  128. /// <summary>
  129. /// 显示提示消息
  130. /// </summary>
  131. /// <param name="msg"></param>
  132. public void ShowMsg(string msg)
  133. {
  134. Invoke(() =>
  135. {
  136. IMsgBoxService.ShowMessage(msg, "提示", MessageButton.OK, MessageIcon.Information);
  137. });
  138. }
  139. /// <summary>
  140. /// 显示警告消息
  141. /// </summary>
  142. /// <param name="msg"></param>
  143. public void ShowWarning(string msg)
  144. {
  145. Invoke(() =>
  146. {
  147. IMsgBoxService.ShowMessage(msg, "警告", MessageButton.OK, MessageIcon.Warning);
  148. });
  149. }
  150. /// <summary>
  151. /// 显示错误消息
  152. /// </summary>
  153. /// <param name="msg"></param>
  154. public void ShowError(string msg)
  155. {
  156. Invoke(() =>
  157. {
  158. IMsgBoxService.ShowMessage(msg, "错误", MessageButton.OK, MessageIcon.Error);
  159. });
  160. }
  161. /// <summary>
  162. /// 显示确认消息
  163. /// </summary>
  164. /// <param name="msg"></param>
  165. /// <returns></returns>
  166. public bool ShowConfirm(string msg)
  167. {
  168. bool res = false;
  169. Invoke(() =>
  170. {
  171. if (!msg.Contains("?") && !msg.Contains("?")) msg += "?";
  172. res = IMsgBoxService.ShowMessage(msg, "确认", MessageButton.YesNo, MessageIcon.Question) == MessageResult.Yes;
  173. });
  174. return res;
  175. }
  176. /// <summary>
  177. /// 显示Overlay窗体
  178. /// </summary>
  179. public void ShowOverlayForm()
  180. {
  181. Invoke(IOverlayService.ShowOverlayForm);
  182. }
  183. /// <summary>
  184. /// 关闭Overlay窗体
  185. /// </summary>
  186. public void CloseOverlayForm()
  187. {
  188. Invoke(IOverlayService.CloseOverlayForm);
  189. }
  190. /// <summary>
  191. /// 显示SplashScreen等待窗体
  192. /// </summary>
  193. /// <param name="caption"></param>
  194. public void ShowWaitForm(string caption)
  195. {
  196. IScreenService.SetSplashScreenState(new string[] { "请稍后", caption });
  197. IScreenService.ShowSplashScreen("MyWaitForm");
  198. }
  199. /// <summary>
  200. /// 关闭SplashScreen等待窗体
  201. /// </summary>
  202. public void CloseWaitForm()
  203. {
  204. Invoke(IScreenService.HideSplashScreen);
  205. }
  206. /// <summary>
  207. /// 显示ViewModel对应的View
  208. /// </summary>
  209. public void ShowCurrentView()
  210. {
  211. ChildViewCancel = true;
  212. Invoke(ICurrentWindowService.Show);
  213. }
  214. /// <summary>
  215. /// 隐藏ViewModel对应的View
  216. /// </summary>
  217. public void HideCurrentView()
  218. {
  219. Invoke(ICurrentWindowService.Hide);
  220. }
  221. /// <summary>
  222. /// 子窗体关闭时是否为取消操作状态.默认true
  223. /// </summary>
  224. public bool ChildViewCancel { get; set; } = true;
  225. /// <summary>
  226. /// 窗体是否为取消状态.默认true
  227. /// </summary>
  228. public bool IsCancel { get; set; } = true;
  229. /// <summary>
  230. /// 关闭ViewModel对应的View
  231. /// </summary>
  232. public void CloseCurrentView()
  233. {
  234. Invoke(ICurrentWindowService.Close);
  235. var pVm = this.GetParentViewModel<BaseVm>();
  236. pVm.ChildViewCancel = IsCancel;
  237. }
  238. /// <summary>
  239. /// 显示指定的View
  240. /// </summary>
  241. public void ShowView(string view, string title, object parameter)
  242. {
  243. ChildViewCancel = true;
  244. IWindowService.Title = title;
  245. IWindowService.Show(view, parameter, this);
  246. }
  247. /// <summary>
  248. /// 隐藏ShowView指定的View
  249. /// </summary>
  250. public void HideView()
  251. {
  252. IWindowService.Hide();
  253. }
  254. /// <summary>
  255. /// 关闭ShowView指定的View
  256. /// </summary>
  257. public void CloseView()
  258. {
  259. IWindowService.Title = "UserClosed";
  260. IWindowService.Close();
  261. var pVm = this.GetParentViewModel<BaseVm>();
  262. pVm.ChildViewCancel = IsCancel;
  263. }
  264. public MessageResult ShowDialogView(string view, string title, MessageButton btn = MessageButton.OKCancel)
  265. {
  266. return IDialogService.ShowDialog(MessageButton.OKCancel, title, view, this);
  267. }
  268. #region service
  269. IDispatcherService IDispatchService => this.GetService<IDispatcherService>();
  270. INotificationService INotifyService => this.GetService<INotificationService>();
  271. IMessageBoxService IMsgBoxService => this.GetService<IMessageBoxService>();
  272. IOverlayFormService IOverlayService => this.GetService<IOverlayFormService>();
  273. ISplashScreenService IScreenService => this.GetService<ISplashScreenService>();
  274. IFolderBrowserDialogService IFolderService => this.GetService<IFolderBrowserDialogService>();
  275. ISaveFileDialogService ISaveFileService => this.GetService<ISaveFileDialogService>();
  276. IOpenFileDialogService IOpenFileService => this.GetService<IOpenFileDialogService>();
  277. ICurrentWindowService ICurrentWindowService => this.GetService<ICurrentWindowService>();
  278. IWindowService IWindowService => this.GetService<IWindowService>();
  279. IDialogService IDialogService => this.GetService<IDialogService>();
  280. #endregion
  281. }