BaseVm.cs 8.8 KB

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