PageEditContentViewModel.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. using Prism.Mvvm;
  2. using Prism.Regions;
  3. using Prism.Services.Dialogs;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Media;
  10. using ComPDFKitViewer.PdfViewer;
  11. using PDF_Office.Model;
  12. using System.Collections.ObjectModel;
  13. using PDF_Office.Model.PageEdit;
  14. using Prism.Commands;
  15. using System.Windows;
  16. using System.Windows.Media.Imaging;
  17. using System.Windows.Controls.Primitives;
  18. using System.Diagnostics;
  19. using System.Windows.Controls;
  20. using PDF_Office.Tools;
  21. using System.Windows.Threading;
  22. using Prism.Events;
  23. using PDF_Office.EventAggregators;
  24. namespace PDF_Office.ViewModels.PageEdit
  25. {
  26. public class PageEditContentViewModel : BindableBase, INavigationAware
  27. {
  28. private CPDFViewer PDFViewer;
  29. private ViewContentViewModel viewContentViewModel;
  30. private IDialogService dialogs;
  31. private IEventAggregator eventor;
  32. /// <summary>
  33. /// 是否正在初始化所有列表项,正在初始化时,不刷新图片
  34. /// </summary>
  35. private bool isInitaling = false;
  36. private ScrollEventType scrollType = ScrollEventType.EndScroll;
  37. /// <summary>
  38. /// 辅助判断滚轮是否暂停滚动的计时器(暂时没有更好的方法来判断滚轮是否停止滚动)
  39. /// 只要滚动就重新计时、通过计时开始0.3秒后没有刷新计时来粗略判断用户是否有暂停滚动
  40. /// </summary>
  41. private DispatcherTimer timer = new DispatcherTimer();
  42. private string unicode = null;
  43. #region 属性
  44. private Visibility isvisible;
  45. public Visibility IsVisible
  46. {
  47. get { return isvisible; }
  48. set
  49. {
  50. SetProperty(ref isvisible, value);
  51. }
  52. }
  53. private int selecedIndex;
  54. /// <summary>
  55. /// 选中项的索引
  56. /// </summary>
  57. public int SelectedIndex
  58. {
  59. get { return selecedIndex; }
  60. set
  61. {
  62. SetProperty(ref selecedIndex, value);
  63. }
  64. }
  65. #endregion
  66. #region 命令
  67. #endregion
  68. /// <summary>
  69. /// 项数据集合
  70. /// </summary>
  71. public ObservableCollection<PageEditItem> PageEditItems { get; set; }
  72. public PageEditContentViewModel(IDialogService dialogService, IEventAggregator eventAggregator)
  73. {
  74. dialogs = dialogService;
  75. eventor = eventAggregator;
  76. unicode = App.mainWindowViewModel.SelectedItem.Unicode;
  77. PageEditItems = new ObservableCollection<PageEditItem>();
  78. eventAggregator.GetEvent<PageEditRefreshEvent>().Subscribe(OnPageEditRefreshEvent, e=>e.Unicode== unicode);
  79. }
  80. #region 事件
  81. private void OnPageEditRefreshEvent(PageEditRefreshEventArgs e)
  82. {
  83. //UI发送事件过来通知刷新图片时
  84. //调整逻辑,前后预加载5页
  85. RefreshItemImage(e.PageRange.Item1-5,e.PageRange.Item2+5);
  86. }
  87. #endregion
  88. /// <summary>
  89. /// 从PDFView获取所有Items集合
  90. /// </summary>
  91. private void GetSourceItems()
  92. {
  93. PageEditItems.Clear();
  94. isInitaling = true;
  95. for (int i = 0; i < PDFViewer.Document.PageCount; i++)
  96. {
  97. PageEditItem item = new PageEditItem();
  98. item.PageNumber = i + 1;
  99. var pagesize = PDFViewer.Document.GetPageSize(i);
  100. item.PageSize = $"{pagesize.Width}mm*{pagesize.Height} mm";
  101. PageEditItems.Add(item);
  102. }
  103. isInitaling = false;
  104. }
  105. /// <summary>
  106. /// 刷新书签列表
  107. /// </summary>
  108. public void RefreshBookMarkList()
  109. {
  110. if (PDFViewer != null)
  111. {
  112. var booklist = PDFViewer.Document.GetBookmarkList();
  113. if (booklist == null)
  114. {
  115. return;
  116. }
  117. //获取所有书签的Index集合
  118. List<int> marks = new List<int>();
  119. for (int i = 0; i < booklist.Count; i++)
  120. {
  121. marks.Add(booklist[i].PageIndex);
  122. }
  123. //不能只遍历marks集合,考虑书签集合元素删除的情况
  124. for (int k = 0; k < PageEditItems.Count; k++)
  125. {
  126. if (marks.Contains(k))
  127. PageEditItems[k].HaveBookMark = true;
  128. else
  129. PageEditItems[k].HaveBookMark = false;
  130. }
  131. }
  132. }
  133. /// <summary>
  134. /// 刷新指定范围的图片
  135. /// </summary>
  136. /// <param name="startIndex"></param>
  137. /// <param name="endIndex"></param>
  138. private async void RefreshItemImage(int startIndex,int endIndex)
  139. {
  140. for (int i = startIndex; i <=endIndex;i++)
  141. {
  142. if (i <= PDFViewer.Document.PageCount - 1&&i>=0)
  143. {
  144. //宽高为样式中图片控件宽高
  145. await PDFViewer.GetThumbnail(i, 208, 294);
  146. }
  147. }
  148. }
  149. #region Navigate
  150. public bool IsNavigationTarget(NavigationContext navigationContext)
  151. {
  152. return true;
  153. }
  154. public void OnNavigatedFrom(NavigationContext navigationContext)
  155. {
  156. }
  157. /// <summary>
  158. /// 从其他页面导航过来的时候会触发
  159. /// 考虑只有在页面编辑的时候会进行页面的删减,可以尝试逻辑优化:仅第一次进入页面编辑时重新刷新页面
  160. /// </summary>
  161. /// <param name="navigationContext"></param>
  162. public void OnNavigatedTo(NavigationContext navigationContext)
  163. {
  164. navigationContext.Parameters.TryGetValue<ViewContentViewModel>(ParameterNames.ViewContentViewModel, out viewContentViewModel);
  165. navigationContext.Parameters.TryGetValue<CPDFViewer>(ParameterNames.PDFViewer, out PDFViewer);
  166. if (PDFViewer != null)
  167. {
  168. PDFViewer.OnThumbnailGenerated += PDFViewer_OnThumbnailGenerated;
  169. GetSourceItems();
  170. RefreshBookMarkList();
  171. }
  172. }
  173. #endregion
  174. /// <summary>
  175. /// 从底层库获取对应页面的图片
  176. /// </summary>
  177. /// <param name="pageIndex"></param>
  178. /// <param name="thumb"></param>
  179. /// <param name="w"></param>
  180. /// <param name="h"></param>
  181. private void PDFViewer_OnThumbnailGenerated(int pageIndex, byte[] thumb, int w, int h)
  182. {
  183. try
  184. {
  185. if (PageEditItems.Count >= pageIndex + 1&&!PageEditItems[pageIndex].IsGetImage)
  186. {
  187. PixelFormat fmt = PixelFormats.Bgra32;
  188. BitmapSource bps = BitmapSource.Create(w, h, 96.0, 96.0, fmt, null, thumb, (w * fmt.BitsPerPixel + 7) / 8);
  189. PageEditItems[pageIndex].Image = bps;
  190. PageEditItems[pageIndex].IsGetImage = true;
  191. }
  192. }
  193. catch
  194. {
  195. }
  196. }
  197. }
  198. }