FolderImageBrowser.xaml.cs 32 KB

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