FolderImageBrowser.xaml.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. using AIPlatform.Protocol.Entities;
  2. using AIPlatform.Protocol.Model;
  3. using AIPlatform.Protocol.Utilities;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Collections.ObjectModel;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. using System.Windows;
  11. using System.Windows.Controls;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. using System.Windows.Media.Imaging;
  15. namespace aipdev
  16. {
  17. public class FolderImageEx
  18. {
  19. public LabeledUltrasoundFile LabeledUltrasoundFile { get; set; }
  20. public DeveloperFolderFile DeveloperFolderFile { get; set; }
  21. /// <summary>
  22. /// Gets the preview image.
  23. /// </summary>
  24. public BitmapImage PreviewImage { get; }
  25. /// <summary>
  26. /// Gets if this image can copy.
  27. /// </summary>
  28. public bool CanCopy { get; }
  29. /// <summary>
  30. /// Gets if this image can be deleted.
  31. /// </summary>
  32. public bool CanDelete { get; }
  33. /// <summary>
  34. /// Gets or sets is selected.
  35. /// </summary>
  36. public bool Selected { get; set; }
  37. public LabeledResult LabeledResult { get; }
  38. public string Conclusions { get; }
  39. public string TrimmingConclusions { get; }
  40. public int Page { get; }
  41. public long SourceFolderId { get; }
  42. public long SourceGroupId { get; }
  43. /// <summary>
  44. /// Gets the value to indicate whether the developer questioned file.
  45. /// </summary>
  46. public bool HasQuestioned { get; }
  47. public FolderImageEx(DeveloperFolderFile image, BitmapImage previewImage, bool canDelete, LabeledResult labeledResult, string conclusions, string trimmingConclusions, int page, long sourceFolderId)
  48. {
  49. DeveloperFolderFile = image;
  50. LabeledUltrasoundFile = null;
  51. PreviewImage = previewImage;
  52. CanCopy = true;
  53. CanDelete = canDelete;
  54. LabeledResult = labeledResult;
  55. Conclusions = conclusions;
  56. TrimmingConclusions = trimmingConclusions;
  57. Page = page;
  58. SourceFolderId = sourceFolderId;
  59. HasQuestioned = image.HasQuestioned;
  60. }
  61. public FolderImageEx(LabeledUltrasoundFile image, BitmapImage previewImage, bool canDelete, LabeledResult labeledResult, string conclusions, string trimmingConclusions, int page, long sourceFolderId, bool hasQuestioned)
  62. {
  63. LabeledUltrasoundFile = image;
  64. DeveloperFolderFile = null;
  65. PreviewImage = previewImage;
  66. CanCopy = true;
  67. CanDelete = canDelete;
  68. LabeledResult = labeledResult;
  69. Conclusions = conclusions;
  70. TrimmingConclusions = trimmingConclusions;
  71. Page = page;
  72. SourceFolderId = sourceFolderId;
  73. HasQuestioned = hasQuestioned;
  74. }
  75. }
  76. /// <summary>
  77. /// Interaction logic for FolderImageViewer.xaml
  78. /// </summary>
  79. public partial class FolderImageBrowser : UserControl, IContentPage
  80. {
  81. private ScrollViewer _scrollViewer;
  82. private string _keyword;
  83. private int _pageSize { get; set; } = 45;
  84. private int _totalPages { get; set; }
  85. private int _preloadedPage { get; set; }
  86. private bool _scrollDown { get; set; }
  87. private bool _isLoadPreviousImages { get; set; }
  88. private bool _isLoadNextImages { get; set; }
  89. private double _oldVerticalOffset { get; set; }
  90. private int _browseImageIndex { get; set; }
  91. private int _browsePage { get; set; }
  92. private int _imageCount { get; set; }
  93. private ImageFolderExtend _folder;
  94. private DeveloperFolderExtend _developerFolder;
  95. private readonly ObservableCollection<FolderImageEx> _images = new ObservableCollection<FolderImageEx>();
  96. public string PageName { get; set; }
  97. public bool IsHomePage { get; set; }
  98. public bool IsModalPage { get; set; }
  99. private bool _stopLoading { get; set; }
  100. private bool _isQuestioned { get; set; }
  101. public FolderImageBrowser()
  102. {
  103. InitializeComponent();
  104. PageName = "FolderImageBrowser";
  105. IsHomePage = false;
  106. IsModalPage = true;
  107. FolderImages.ItemsSource = _images;
  108. }
  109. private T FindVisualChild<T>(DependencyObject element) where T : class
  110. {
  111. try
  112. {
  113. while (element != null)
  114. {
  115. if (element is T)
  116. return element as T;
  117. element = VisualTreeHelper.GetChild(element, 0);
  118. }
  119. }
  120. catch (Exception)
  121. {
  122. //DoNothing
  123. }
  124. return null;
  125. }
  126. private void OnFolderImagesScrollChanged(object sender, ScrollChangedEventArgs e)
  127. {
  128. var scrollViewer = (ScrollViewer)sender;
  129. if (IsOnScrollViewBottom(scrollViewer))
  130. {
  131. if (_preloadedPage < _totalPages)
  132. {
  133. try
  134. {
  135. Task.Run(async () =>
  136. {
  137. await LoadImagesAsync(_preloadedPage).ConfigureAwait(false);
  138. });
  139. }
  140. catch (Exception ex)
  141. {
  142. MessageBox.Show(Application.Current.MainWindow, $"加载文件夹图像失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  143. }
  144. }
  145. }
  146. }
  147. private bool IsOnScrollViewBottom(ScrollViewer view)
  148. {
  149. var onBottom = false;
  150. var verticalOffset = view.VerticalOffset;
  151. var scrollableHeight = view.ScrollableHeight;
  152. var extentHeight = view.ExtentHeight;
  153. _scrollDown = verticalOffset >= _oldVerticalOffset;
  154. #region 滚动条从上往下翻看,加载之面页数
  155. if (_scrollDown && verticalOffset / extentHeight > 0.7 && _stopLoading && _preloadedPage < _totalPages - 1)
  156. {
  157. _isLoadNextImages = true;
  158. _isLoadPreviousImages = false;
  159. onBottom = true;
  160. verticalOffset = 2;
  161. _preloadedPage++;
  162. }
  163. #endregion 滚动条从上往下翻看,加载之面页数
  164. #region 有上一次的浏览记录时,滚动条从下往上翻看,加载之前页数
  165. else if (_browsePage > 0 && !_scrollDown && verticalOffset / extentHeight < 0.3 && _stopLoading && _preloadedPage > 0)
  166. {
  167. _isLoadPreviousImages = true;
  168. _isLoadNextImages = false;
  169. onBottom = true;
  170. verticalOffset = scrollableHeight;
  171. _preloadedPage--;
  172. }
  173. #endregion 有上一次的浏览记录时,滚动条从下往上翻看,加载之前页数
  174. _oldVerticalOffset = verticalOffset;
  175. return onBottom;
  176. }
  177. public void Close()
  178. {
  179. ClearImages();
  180. }
  181. private string GetConclusions(List<LabelConclusion> labelConclusions, ref string trimmingConclusions)
  182. {
  183. var conclusions = string.Empty;
  184. for (int i = 0; i < labelConclusions.Count; i++)
  185. {
  186. var item = labelConclusions[i];
  187. conclusions += $"{item.Title} {item.Content}";
  188. if (i < labelConclusions.Count - 1)
  189. conclusions += Environment.NewLine;
  190. if (i < 5)
  191. {
  192. trimmingConclusions = conclusions;
  193. }
  194. else if (i == 5)
  195. {
  196. trimmingConclusions += "......";
  197. }
  198. }
  199. return conclusions;
  200. }
  201. private string GetConclusions(LabeledResult labeledResult, ref string trimmingConclusions)
  202. {
  203. var i = 0;
  204. var conclusions = string.Empty;
  205. var num = 0;
  206. if (labeledResult.ImageResults.Any(x => x.Index == 0))
  207. {
  208. num = 1;
  209. }
  210. foreach (var imageResult in labeledResult.ImageResults)
  211. {
  212. conclusions = $"[图像结论-{imageResult.Index + num}] {imageResult.Conclusion.Title}";
  213. if (i < 5)
  214. {
  215. trimmingConclusions = conclusions;
  216. }
  217. else if (i == 5)
  218. {
  219. trimmingConclusions += Environment.NewLine + "......";
  220. }
  221. i++;
  222. }
  223. num = 0;
  224. if (labeledResult.Rois.Any(x => x.Index == 0))
  225. {
  226. num = 1;
  227. }
  228. foreach (var roi in labeledResult.Rois)
  229. {
  230. if (roi.Conclusion != null)
  231. {
  232. if (!string.IsNullOrEmpty(conclusions))
  233. {
  234. conclusions += Environment.NewLine;
  235. }
  236. conclusions += $"[ROI结论-{roi.Index + num}] {roi.Conclusion.Title}";
  237. if (i < 5)
  238. {
  239. trimmingConclusions = conclusions;
  240. }
  241. else if (i == 5)
  242. {
  243. trimmingConclusions += Environment.NewLine + "......";
  244. }
  245. i++;
  246. }
  247. }
  248. return conclusions;
  249. }
  250. private async Task LoadImagesAsync(int page = 0)
  251. {
  252. try
  253. {
  254. Dispatcher.Invoke(() =>
  255. {
  256. ContentManager.ShowLoading();
  257. });
  258. _stopLoading = false;
  259. if (_developerFolder is DeveloperFolder developerImageFolder)
  260. {
  261. var editable = developerImageFolder.DeveloperId == DeveloperManager.Shared.Session.AccountId;
  262. var folderImages = await DeveloperManager.Shared.GetDeveloperFolderFileInfosAsync(developerImageFolder.Id, _keyword, _isQuestioned, page, _pageSize).ConfigureAwait(false);
  263. if (_isLoadPreviousImages)
  264. {
  265. folderImages = folderImages.OrderByDescending(x => x.DeveloperFolderFile.Index).ToList();
  266. }
  267. foreach (var folderImage in folderImages)
  268. {
  269. if (_images.Any(x => x.DeveloperFolderFile.DeveloperFolderGroupId == folderImage.DeveloperFolderFile.DeveloperFolderGroupId))
  270. {
  271. continue;
  272. }
  273. var imageData = SkiaSharpHelper.GetLabeledImageData(folderImage.FirstFileArchivedImage.ImageData, folderImage.FirstFileArchivedImage.Width, folderImage.FirstFileArchivedImage.Height, folderImage.FirstFileDeveloperLabeledResult.Rois);
  274. var previewImage = new BitmapImage();
  275. previewImage.BeginInit();
  276. previewImage.StreamSource = new MemoryStream(imageData);
  277. previewImage.EndInit();
  278. previewImage.Freeze();
  279. var trimmingConclusions = string.Empty;
  280. var conclusions = GetConclusions(folderImage.FirstFileDeveloperLabeledResult, ref trimmingConclusions);
  281. var folderImageEx = new FolderImageEx(folderImage.DeveloperFolderFile, previewImage, editable, folderImage.FirstFileDeveloperLabeledResult, conclusions, trimmingConclusions, page, developerImageFolder.Id);
  282. if (_stopLoading)
  283. {
  284. break;
  285. }
  286. if (_isLoadPreviousImages)
  287. {
  288. Dispatcher.Invoke(() =>
  289. {
  290. _images.Insert(0, folderImageEx);
  291. });
  292. }
  293. else
  294. {
  295. Dispatcher.Invoke(() =>
  296. {
  297. _images.Add(folderImageEx);
  298. });
  299. }
  300. }
  301. }
  302. else if (_folder is ImageFolderExtend imageFolder)
  303. {
  304. var labeledFileInfos = await DeveloperManager.Shared.GetLatestLabeledFileInfosAsync(imageFolder.Id, _keyword, _isQuestioned, false, page, _pageSize);
  305. if (_isLoadPreviousImages)
  306. {
  307. labeledFileInfos = labeledFileInfos.OrderByDescending(x => x).ToList();
  308. }
  309. foreach (var fileInfo in labeledFileInfos)
  310. {
  311. var labeledUltrasoundFile = fileInfo.LabeledUltrasoundFile;
  312. if (_images.Any(x => x.LabeledUltrasoundFile.UltrasoundGroupId == labeledUltrasoundFile.UltrasoundGroupId))
  313. {
  314. continue;
  315. }
  316. var previewImage = new BitmapImage();
  317. previewImage.BeginInit();
  318. previewImage.StreamSource = new MemoryStream(fileInfo.ImageData);
  319. previewImage.EndInit();
  320. previewImage.Freeze();
  321. var trimmingConclusions = string.Empty;
  322. var conclusions = GetConclusions(fileInfo.LabelConclusions, ref trimmingConclusions);
  323. var folderImageEx = new FolderImageEx(labeledUltrasoundFile, previewImage, false, fileInfo.LabeledResult, conclusions, trimmingConclusions, page, imageFolder.Id, fileInfo.HasQuestioned);
  324. if (_stopLoading)
  325. {
  326. break;
  327. }
  328. if (_isLoadPreviousImages)
  329. {
  330. Dispatcher.Invoke(() =>
  331. {
  332. _images.Insert(0, folderImageEx);
  333. });
  334. }
  335. else
  336. {
  337. Dispatcher.Invoke(() =>
  338. {
  339. _images.Add(folderImageEx);
  340. });
  341. }
  342. }
  343. }
  344. _stopLoading = true;
  345. Dispatcher.Invoke(() =>
  346. {
  347. if (_scrollViewer == null)
  348. {
  349. _scrollViewer = FindVisualChild<ScrollViewer>(FolderImages);
  350. if (_scrollViewer != null)
  351. {
  352. if (_browseImageIndex == 0)
  353. {
  354. _scrollViewer.ScrollToTop();
  355. }
  356. else
  357. {
  358. var rowHeight = _scrollViewer.ExtentHeight / Math.Ceiling((double)_images.Count / 3);
  359. var count = _browseImageIndex % _pageSize;
  360. var verticalOffset = Math.Floor((double)count / 3) * rowHeight;
  361. _scrollViewer.ScrollToVerticalOffset(verticalOffset);
  362. }
  363. _scrollViewer.ScrollChanged += OnFolderImagesScrollChanged;
  364. }
  365. }
  366. else if (_isLoadPreviousImages)
  367. {
  368. var rowHeight = _scrollViewer.ExtentHeight / Math.Ceiling((double)_images.Count / 3);
  369. var verticalOffset = _pageSize / 3 * rowHeight + _scrollViewer.VerticalOffset;
  370. _scrollViewer.ScrollToVerticalOffset(verticalOffset);
  371. }
  372. });
  373. }
  374. catch (Exception ex)
  375. {
  376. Dispatcher.Invoke(() =>
  377. {
  378. MessageBox.Show(Application.Current.MainWindow, $"加载文件夹图像失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  379. });
  380. }
  381. finally
  382. {
  383. Dispatcher.Invoke(() =>
  384. {
  385. ContentManager.HideLoading();
  386. });
  387. }
  388. }
  389. private void ClearImages()
  390. {
  391. Reset();
  392. _folder = null;
  393. _developerFolder = null;
  394. FolderName.Text = string.Empty;
  395. FolderName.ToolTip = string.Empty;
  396. _keyword = txtFileName.Text = string.Empty;
  397. txtIndex.Text = string.Empty;
  398. _totalPages = 0;
  399. _imageCount = 0;
  400. chbIsQuestioned.IsChecked = false;
  401. _isQuestioned = false;
  402. }
  403. public async void OnShow(object arg)
  404. {
  405. try
  406. {
  407. if (arg is ImageFolderExtend imageFolder)
  408. {
  409. _folder = imageFolder;
  410. FolderName.Text = _folder.Name;
  411. FolderName.ToolTip = _folder.Name;
  412. _imageCount = _folder.GroupCount;
  413. _totalPages = (int)Math.Ceiling((double)_imageCount / _pageSize);
  414. JumpIndex.Visibility = Visibility.Collapsed;
  415. //#region 加载历史查看位置
  416. //if (_folder is DeveloperImageFolder developerImageFolder)
  417. //{
  418. // var findBrowseInfo = await DeveloperManager.Shared.GetDeveloperFolderBrowseHistoricalInfo(developerImageFolder.Id);
  419. // if (findBrowseInfo != null)
  420. // {
  421. // _browseImageIndex = findBrowseInfo.BrowseImageIndex;
  422. // _browsePage = findBrowseInfo.BrowsePage;
  423. // _preloadedPage = findBrowseInfo.BrowsePage;
  424. // }
  425. //}
  426. //#endregion
  427. await LoadImagesAsync(_preloadedPage).ConfigureAwait(false);
  428. }
  429. else if (arg is DeveloperFolderExtend developerFolder)
  430. {
  431. _developerFolder = developerFolder;
  432. FolderName.Text = _developerFolder.Name;
  433. FolderName.ToolTip = _developerFolder.Name;
  434. _imageCount = _developerFolder.GroupCount;
  435. _totalPages = (int)Math.Ceiling((double)_imageCount / _pageSize);
  436. JumpIndex.Visibility = Visibility.Visible;
  437. await LoadImagesAsync(_preloadedPage).ConfigureAwait(false);
  438. }
  439. else
  440. {
  441. throw new InvalidOperationException("无效的文件夹路径。");
  442. }
  443. }
  444. catch (Exception ex)
  445. {
  446. MessageBox.Show(Application.Current.MainWindow, $"加载文件夹图像失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  447. }
  448. }
  449. public void OnHide()
  450. {
  451. ClearImages();
  452. }
  453. private async void OnImageClick(object sender, RoutedEventArgs e)
  454. {
  455. FolderImageEx folderImageEx = null;
  456. if (sender is MenuItem menuItem)
  457. {
  458. folderImageEx = (FolderImageEx)menuItem.DataContext;
  459. }
  460. else if (sender is Button button)
  461. {
  462. folderImageEx = (FolderImageEx)button.DataContext;
  463. }
  464. if (folderImageEx != null)
  465. {
  466. if (folderImageEx.LabeledUltrasoundFile != null)
  467. {
  468. var groupIds = _images.Select(x => x.LabeledUltrasoundFile.UltrasoundGroupId).ToList();
  469. var lstLabeledFileId = _images.Select(x => x.LabeledUltrasoundFile.Id).ToList();
  470. var groupIndex = groupIds.IndexOf(folderImageEx.LabeledUltrasoundFile.UltrasoundGroupId);
  471. var folderImageViewer = new FolderImageViewer(folderImageEx.SourceFolderId, folderImageEx.SourceGroupId, groupIndex, folderImageEx.LabeledUltrasoundFile, groupIds, lstLabeledFileId) { Owner = Application.Current.MainWindow };
  472. folderImageViewer.ShowDialog();
  473. }
  474. else
  475. {
  476. var developerLabeledUltrasoundFile = await DeveloperManager.Shared.GetDeveloperLabeledUltrasoundFileAsync(folderImageEx.DeveloperFolderFile.DeveloperLabeledUltrasoundInfoList[0].DeveloperLabeledUltrasoundFileId);
  477. var groupIds = _images.Select(x => x.DeveloperFolderFile.UltrasoundGroupId).ToList();
  478. var lstIndex = _images.Select(x => x.DeveloperFolderFile.Index).ToList();
  479. var lstLabeledFileId = _images.Select(x => x.DeveloperFolderFile.DeveloperLabeledUltrasoundInfoList[0].DeveloperLabeledUltrasoundFileId).ToList();
  480. var groupIndex = groupIds.IndexOf(folderImageEx.DeveloperFolderFile.UltrasoundGroupId);
  481. var folderImageViewer = new FolderImageViewer(folderImageEx.SourceFolderId, folderImageEx.SourceGroupId, groupIndex, developerLabeledUltrasoundFile, groupIds, lstLabeledFileId, lstIndex) { Owner = Application.Current.MainWindow };
  482. folderImageViewer.ShowDialog();
  483. }
  484. }
  485. }
  486. private async void OnDeleteFileClick(object sender, RoutedEventArgs e)
  487. {
  488. var menuItem = (MenuItem)sender;
  489. var folderImageEx = (FolderImageEx)menuItem.DataContext;
  490. var result = MessageBox.Show(Application.Current.MainWindow, "是否删除该图片?", "删除图片", MessageBoxButton.YesNo, MessageBoxImage.Question);
  491. if (result == MessageBoxResult.Yes)
  492. {
  493. try
  494. {
  495. Dispatcher.Invoke(() =>
  496. {
  497. ContentManager.ShowLoading();
  498. });
  499. await DeveloperManager.Shared.DeleteDeveloperFolderGroupAsync(folderImageEx.DeveloperFolderFile.DeveloperFolderGroupId);
  500. Dispatcher.Invoke(() =>
  501. {
  502. var startIndex = _images.IndexOf(folderImageEx);
  503. _images.Remove(folderImageEx);
  504. for (int i = startIndex; i < _images.Count; i++)
  505. {
  506. var image = _images[i];
  507. image.DeveloperFolderFile.Index--;
  508. }
  509. _imageCount--;
  510. });
  511. }
  512. catch (Exception ex)
  513. {
  514. MessageBox.Show(Application.Current.MainWindow, $"删除图片失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  515. }
  516. finally
  517. {
  518. Dispatcher.Invoke(() =>
  519. {
  520. ContentManager.HideLoading();
  521. });
  522. }
  523. }
  524. }
  525. private async void OnCopyFileClick(object sender, RoutedEventArgs e)
  526. {
  527. var menuItem = (MenuItem)sender;
  528. var folderImageEx = (FolderImageEx)menuItem.DataContext;
  529. try
  530. {
  531. CopyImageWindow copyImageWindow;
  532. if (folderImageEx.DeveloperFolderFile != null)
  533. {
  534. copyImageWindow = new CopyImageWindow(folderImageEx.DeveloperFolderFile.ImageCategoryId) { Owner = Application.Current.MainWindow };
  535. }
  536. else
  537. {
  538. copyImageWindow = new CopyImageWindow(folderImageEx.LabeledUltrasoundFile.ImageCategoryId) { Owner = Application.Current.MainWindow };
  539. }
  540. copyImageWindow.ShowDialog();
  541. var selectedFolder = copyImageWindow.SelectedFolder;
  542. if (selectedFolder != null)
  543. {
  544. Dispatcher.Invoke(() =>
  545. {
  546. ContentManager.ShowLoading();
  547. });
  548. try
  549. {
  550. if (folderImageEx.DeveloperFolderFile != null)
  551. {
  552. await DeveloperManager.Shared.CopyDeveloperFolderGroupAsync(selectedFolder.Id, folderImageEx.SourceFolderId, folderImageEx.DeveloperFolderFile.UltrasoundGroupId);
  553. }
  554. else
  555. {
  556. await DeveloperManager.Shared.CopyFolderGroupAsync(selectedFolder.Id, folderImageEx.SourceFolderId, folderImageEx.LabeledUltrasoundFile.UltrasoundGroupId);
  557. }
  558. }
  559. catch (Exception ex)
  560. {
  561. MessageBox.Show(Application.Current.MainWindow, $"复制图片失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  562. }
  563. finally
  564. {
  565. Dispatcher.Invoke(() =>
  566. {
  567. ContentManager.HideLoading();
  568. });
  569. }
  570. }
  571. }
  572. catch (Exception ex)
  573. {
  574. MessageBox.Show(Application.Current.MainWindow, $"获取文件夹列表失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  575. }
  576. }
  577. private void OnCloseClick(object sender, RoutedEventArgs e)
  578. {
  579. ClearImages();
  580. this.Hide();
  581. }
  582. private void OnSearchFiles(object sender, RoutedEventArgs e)
  583. {
  584. _keyword = txtFileName.Text;
  585. Reset();
  586. Task.Run(async () =>
  587. {
  588. await LoadImagesAsync().ConfigureAwait(false);
  589. });
  590. }
  591. private async void txtIndex_PreviewKeyDown(object sender, KeyEventArgs e)
  592. {
  593. try
  594. {
  595. if (e.Key == Key.Enter)
  596. {
  597. if (int.TryParse(txtIndex.Text, out var imageIndex))
  598. {
  599. if (imageIndex >= _imageCount || imageIndex < 0)
  600. {
  601. MessageBox.Show(Application.Current.MainWindow, $"跳转图像超出索引最大值 {_imageCount - 1}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  602. return;
  603. }
  604. #region Clear
  605. Reset();
  606. #endregion Clear
  607. #region 跳转到指定位置
  608. _browseImageIndex = imageIndex;
  609. _preloadedPage = _browsePage = (int)Math.Ceiling((double)imageIndex / _pageSize) - 1;
  610. await LoadImagesAsync(_preloadedPage).ConfigureAwait(false);
  611. #endregion 跳转到指定位置
  612. }
  613. }
  614. }
  615. catch (Exception ex)
  616. {
  617. MessageBox.Show(Application.Current.MainWindow, $"跳转图像失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  618. }
  619. }
  620. private void Reset()
  621. {
  622. _scrollViewer ??= FindVisualChild<ScrollViewer>(FolderImages);
  623. if (_scrollViewer != null)
  624. {
  625. //#region 保存历史查看位置
  626. //if (_folder is DeveloperImageFolder developerImageFolder)
  627. //{
  628. // try
  629. // {
  630. // var rowHeight = _scrollViewer.ExtentHeight / Math.Ceiling((double)_images.Count / 3);
  631. // var currRows = Math.Ceiling(_scrollViewer.VerticalOffset / rowHeight);
  632. // _browseImageIndex = (int)currRows * 3;
  633. // _browsePage = _images[_browseImageIndex].Page;
  634. // await DeveloperManager.Shared.UpdateDeveloperFolderBrowseHistoricalInfo(_folder.Id, _browseImageIndex, _browsePage);
  635. // }
  636. // catch (Exception ex)
  637. // {
  638. // MessageBox.Show(Application.Current.MainWindow, $"保存文件夹浏览记录失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  639. // }
  640. //}
  641. //#endregion
  642. _scrollViewer.ScrollChanged -= OnFolderImagesScrollChanged;
  643. }
  644. _stopLoading = true;
  645. _scrollViewer = null;
  646. _images.Clear();
  647. _preloadedPage = 0;
  648. _isLoadPreviousImages = false;
  649. _isLoadNextImages = false;
  650. _scrollDown = false;
  651. _oldVerticalOffset = 0;
  652. _browseImageIndex = 0;
  653. _browsePage = 0;
  654. }
  655. private void OnClearAndSearchFiles(object sender, RoutedEventArgs e)
  656. {
  657. _keyword = txtFileName.Text = string.Empty;
  658. txtIndex.Text = string.Empty;
  659. OnSearchFiles(sender, e);
  660. }
  661. private void txtFileName_PreviewKeyDown(object sender, KeyEventArgs e)
  662. {
  663. if (e.Key == Key.Enter)
  664. {
  665. OnSearchFiles(sender, e);
  666. }
  667. }
  668. private async void OnSuspectedMislabeledFileClick(object sender, RoutedEventArgs e)
  669. {
  670. var menuItem = (MenuItem)sender;
  671. var folderImageEx = (FolderImageEx)menuItem.DataContext;
  672. try
  673. {
  674. CopyImageWindow copyImageWindow;
  675. if (folderImageEx.DeveloperFolderFile != null)
  676. {
  677. copyImageWindow = new CopyImageWindow(folderImageEx.DeveloperFolderFile.ImageCategoryId) { Owner = Application.Current.MainWindow };
  678. }
  679. else
  680. {
  681. copyImageWindow = new CopyImageWindow(folderImageEx.LabeledUltrasoundFile.ImageCategoryId) { Owner = Application.Current.MainWindow };
  682. }
  683. copyImageWindow.ShowDialog();
  684. var selectedFolder = copyImageWindow.SelectedFolder;
  685. if (selectedFolder != null)
  686. {
  687. Dispatcher.Invoke(() =>
  688. {
  689. ContentManager.ShowLoading();
  690. });
  691. try
  692. {
  693. if (folderImageEx.DeveloperFolderFile != null)
  694. {
  695. await DeveloperManager.Shared.CopyDeveloperFolderGroupAsync(selectedFolder.Id, folderImageEx.SourceFolderId, folderImageEx.DeveloperFolderFile.UltrasoundGroupId);
  696. }
  697. else
  698. {
  699. await DeveloperManager.Shared.CopyFolderGroupAsync(selectedFolder.Id, folderImageEx.SourceFolderId, folderImageEx.LabeledUltrasoundFile.UltrasoundGroupId);
  700. }
  701. }
  702. catch (Exception ex)
  703. {
  704. MessageBox.Show(Application.Current.MainWindow, $"复制图片失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  705. }
  706. finally
  707. {
  708. Dispatcher.Invoke(() =>
  709. {
  710. ContentManager.HideLoading();
  711. });
  712. }
  713. }
  714. }
  715. catch (Exception ex)
  716. {
  717. MessageBox.Show(Application.Current.MainWindow, $"获取文件夹列表失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  718. }
  719. }
  720. private void OnQuestionedFilesClick(object sender, RoutedEventArgs e)
  721. {
  722. _isQuestioned = (bool)chbIsQuestioned.IsChecked;
  723. OnSearchFiles(sender, e);
  724. }
  725. }
  726. }