UCPatchGrid.xaml.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. using MeterVision.Config;
  2. using MeterVision.db;
  3. using MeterVision.Dlg;
  4. using MeterVision.FreeAi;
  5. using MeterVision.model;
  6. using MeterVision.Util;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Collections.ObjectModel;
  10. using System.ComponentModel;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. using System.Windows;
  17. using System.Windows.Controls;
  18. using System.Windows.Data;
  19. using System.Windows.Documents;
  20. using System.Windows.Input;
  21. using System.Windows.Media;
  22. using System.Windows.Media.Imaging;
  23. using System.Windows.Navigation;
  24. using System.Windows.Shapes;
  25. namespace MeterVision.Patch
  26. {
  27. /// <summary>
  28. /// UCPatchGrid.xaml 的交互逻辑
  29. /// </summary>
  30. public partial class UCPatchGrid : UserControl, INotifyPropertyChanged
  31. {
  32. public event PropertyChangedEventHandler PropertyChanged;
  33. protected void OnPropertyChanged(string propertyName)
  34. {
  35. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  36. }
  37. //定义任务详情数据源
  38. public ObservableCollection<PatchDetailItem> PatchDetailItemList { get; set; }
  39. // 定义事件,用于通知外部组件选中项已更改
  40. public event EventHandler<PatchDetailItemChangedEventArgs> OnSelectedPatchDetailItemChanged;
  41. public event Action<string> OnRefreshPatchItem;
  42. //删除标准模板明细事件
  43. public static event Action<string> OnDeleteStandDetail;
  44. //修改标准模板值事件
  45. public static event Action<string,string> OnUpdateStandValue;
  46. private PatchDetailItem _selectedPatchDetailItem;
  47. //定义SelectedDataItem属性,并在值变化时触发事件
  48. public PatchDetailItem SelectedPatchDetailItem
  49. {
  50. get => _selectedPatchDetailItem;
  51. set
  52. {
  53. if (_selectedPatchDetailItem != value)
  54. {
  55. _selectedPatchDetailItem = value;
  56. OnPropertyChanged(nameof(SelectedPatchDetailItem));
  57. OnSelectedPatchDetailItemChanged?.Invoke(this, new PatchDetailItemChangedEventArgs(value));
  58. }
  59. }
  60. }
  61. private PatchItem _curPatchItem;
  62. private PatchItem CurPatchItem
  63. {
  64. get => _curPatchItem;
  65. set
  66. {
  67. if (_curPatchItem != value)
  68. {
  69. _curPatchItem = value;
  70. //PatchDetailPage.InitDefaulValue(mConfigItem.PatchPageSize);
  71. //PatchDetailPage.InitDefaulValue();
  72. //LoadPatchDetailItemList();
  73. }
  74. }
  75. }
  76. //此属性只在函数内部调用
  77. private VPatchStation _curStationItem;
  78. private VPatchStation CurStationItem
  79. {
  80. get => _curStationItem;
  81. set
  82. {
  83. if (_curStationItem != value)
  84. {
  85. _curStationItem = value;
  86. //PatchDetailPage.InitDefaulValue(mConfigItem.StandPageSize);
  87. //LoadStandDetailItemList();
  88. }
  89. }
  90. }
  91. private PatchFindType _selectedPatchFindType;
  92. private PatchFindType SelectedPatchFindType
  93. {
  94. get => _selectedPatchFindType;
  95. set
  96. {
  97. if (_selectedPatchFindType != value)
  98. {
  99. _selectedPatchFindType = value;
  100. //OnPropertyChanged(nameof(SelectedPatchFindType));
  101. //PatchDetailPage.InitDefaulValue();
  102. }
  103. }
  104. }
  105. //改变PatchItem或PatchFinType
  106. public void ChangePatchItemOrFinType(PatchItem curPatchItem,VPatchStation curStationItem,PatchFindType patchFindType)
  107. {
  108. bool blPatchItemChanged = false;
  109. bool blPatchFindTypeChanged = false;
  110. bool blStationChanged = false;
  111. //判断是否数据发生变化
  112. if(curPatchItem != _curPatchItem)
  113. {
  114. CurPatchItem = curPatchItem;
  115. blPatchItemChanged = true;
  116. }
  117. if(curStationItem != _curStationItem)
  118. {
  119. CurStationItem = curStationItem;
  120. blStationChanged = true;
  121. }
  122. if(patchFindType != _selectedPatchFindType)
  123. {
  124. SelectedPatchFindType = patchFindType;
  125. blPatchFindTypeChanged = true;
  126. }
  127. if(blPatchItemChanged || blPatchFindTypeChanged || blStationChanged)
  128. {
  129. PatchDetailPage.InitDefaulValue();
  130. LoadPatchDetailItemList(true);
  131. }
  132. }
  133. public CfginiItem mConfigItem { get; set; }
  134. public PageModel PatchDetailPage { get; set; }
  135. private int _totalRecord;
  136. public int TotalRecords
  137. {
  138. get => _totalRecord;
  139. set
  140. {
  141. if (_totalRecord != value)
  142. {
  143. _totalRecord = value;
  144. OnPropertyChanged(nameof(TotalRecords));
  145. }
  146. }
  147. }
  148. public UCPatchGrid()
  149. {
  150. InitializeComponent();
  151. PatchDetailItemList = new ObservableCollection<PatchDetailItem>();
  152. dgPatchDetail.ItemsSource = PatchDetailItemList;
  153. mConfigItem = CfginiItem.GetConfigItem();
  154. PatchDetailPage = new PageModel
  155. {
  156. PageSize = mConfigItem.PatchPageSize,
  157. PageNumber = 1
  158. };
  159. //mConfigItem.OnPatchPageSizeChanged += MConfigItem_OnPatchPageSizeChanged;
  160. mConfigItem.OnPatchPageSizeChanged += MConfigItem_OnPatchPageSizeChanged;
  161. this.DataContext = this;
  162. }
  163. private void MConfigItem_OnPatchPageSizeChanged(int pageSize)
  164. {
  165. PatchDetailPage.InitDefaulValue(pageSize);
  166. LoadPatchDetailItemList(true);
  167. }
  168. //private void MConfigItem_OnPatchPageSizeChanged(object sender, PageSizeChangedEventArgs e)
  169. //{
  170. // PatchDetailPage.InitDefaulValue(e.PageSize);
  171. // LoadPatchDetailItemList(true);
  172. //}
  173. //private async void LoadPatchDetailItemList(bool scrollTop)
  174. private void LoadPatchDetailItemList(bool scrollTop)
  175. {
  176. PatchDetailItemList.Clear();
  177. if (CurPatchItem != null )
  178. {
  179. try
  180. {
  181. //var result = await Task.Run(() =>
  182. //{
  183. //数据库查询
  184. //return DBPatch.GetPagedPatchDetails(
  185. // PatchDetailPage.PageNumber, PatchDetailPage.PageSize, CurPatchItem.PatchId);
  186. string stationId = CurStationItem == null ? "" : CurStationItem.StationId;
  187. PatchFindModel findModel = new PatchFindModel(PatchDetailPage.PageNumber, PatchDetailPage.PageSize,
  188. CurPatchItem.PatchId,stationId ,SelectedPatchFindType);
  189. // return DBPatch.GetPagedPatchDetails(findModel);
  190. //});
  191. var result = DBPatch.GetPagedPatchDetails(findModel);
  192. //更新分页信息
  193. TotalRecords = result.Item1;
  194. PatchDetailPage.PageCount = result.Item2;
  195. List<TPatchDetail> patchDetails = result.Item3;
  196. //更新数据需要在主线中进行
  197. //Application.Current.Dispatcher.Invoke(() =>
  198. //{
  199. int index = 0;
  200. foreach (TPatchDetail patchDetail in patchDetails)
  201. {
  202. index++;
  203. PatchDetailItem item = new PatchDetailItem(patchDetail);
  204. item.Index = index + ((PatchDetailPage.PageNumber - 1) * PatchDetailPage.PageSize);
  205. PatchDetailItemList.Add(item);
  206. }//foreach
  207. SelectedPatchDetailItem = null;
  208. if (PatchDetailItemList.Count > 0 && scrollTop)
  209. {
  210. dgPatchDetail.ScrollIntoView(dgPatchDetail.Items[0]);
  211. }
  212. //});
  213. }
  214. catch (Exception ex)
  215. {
  216. MessageBox.Show(Application.Current.MainWindow,
  217. $"加载数据时发生错误:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  218. }
  219. }
  220. SelectedPatchDetailItem = null;
  221. }
  222. private void StandResultTextBlock_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  223. {
  224. // 检查是否是双击
  225. if (e.ClickCount == 2)
  226. {
  227. // 获取当前行的数据上下文
  228. var textBlock = sender as TextBlock;
  229. if (textBlock == null) return;
  230. var dataContext = textBlock.DataContext as PatchDetailItem; // 替换为你的数据类型
  231. if (dataContext == null) return;
  232. SelectedPatchDetailItem = dataContext;
  233. StandValueModel standValueModel = new StandValueModel(dataContext);
  234. var dialog = new EditStandValueDlg(standValueModel)
  235. {
  236. Owner = Application.Current.MainWindow,
  237. WindowStartupLocation = WindowStartupLocation.CenterOwner
  238. };
  239. //if(dialog.ShowDialog() == true)
  240. //{
  241. // UpdatePatchDetailStandValue(dataContext, standValueModel);
  242. //}//if showDialog
  243. dialog.OnEditStandValue += (value) =>
  244. {
  245. UpdatePatchDetailStandValue(dataContext, standValueModel);
  246. };
  247. dialog.Show();
  248. }//e.clickCount
  249. }
  250. private void UpdateStandvalue(PatchDetailItem detailItem)
  251. {
  252. StandValueModel standValueModel = new StandValueModel(detailItem);
  253. var dialog = new EditStandValueDlg(standValueModel)
  254. {
  255. Owner = Application.Current.MainWindow,
  256. WindowStartupLocation = WindowStartupLocation.CenterOwner
  257. };
  258. //if (dialog.ShowDialog() == true)
  259. //{
  260. // UpdatePatchDetailStandValue(detailItem, standValueModel);
  261. //}//if showDialog
  262. dialog.OnEditStandValue += (value) =>
  263. {
  264. UpdatePatchDetailStandValue(detailItem, standValueModel);
  265. };
  266. dialog.Show();
  267. }
  268. private void UpdatePatchDetailStandValue(PatchDetailItem detailItem, StandValueModel standValueModel)
  269. {
  270. try
  271. {
  272. //修改数据库
  273. //判断detailItem中的FinalValue与标准值是否相等
  274. int equalFlag = 0;
  275. if(int.TryParse(standValueModel.StandValue,out int iStandValue))
  276. {
  277. //equalFlag = detailItem.CheckEquailityWithStandValue(iStandValue, detailItem.FinalValue) ? 1 : 0;
  278. equalFlag = detailItem.GetEqualFlag(iStandValue, detailItem.FinalValue);
  279. }
  280. bool updateStandValue1 = DBPatch.UpdatePatchDetailStandValue(detailItem.PatchDetailId, standValueModel.StandValue,equalFlag);
  281. bool updateStandValue2 = DBStand.UpdateStandDetailStandValue(detailItem.SrcImage, standValueModel.StandValue);
  282. if (updateStandValue1 && updateStandValue2)
  283. {
  284. detailItem.StandValue = standValueModel.StandValue;
  285. detailItem.EqualFlag = equalFlag;
  286. //MessageBox.Show(Application.Current.MainWindow, "修改标准值完成。", "提示", MessageBoxButton.OK,
  287. // MessageBoxImage.Information);
  288. //应该更新目录内容
  289. OnRefreshPatchItem?.Invoke(detailItem.PatchId);
  290. OnUpdateStandValue?.Invoke(detailItem.StandDetailId, detailItem.StandValue);
  291. }
  292. else
  293. {
  294. MessageBox.Show(Application.Current.MainWindow, "修改标准值失败。", "警告", MessageBoxButton.OK,
  295. MessageBoxImage.Warning);
  296. }
  297. }
  298. catch (Exception ex)
  299. {
  300. MessageBox.Show(Application.Current.MainWindow, $"修改标准值错误:{ex.Message}!", "警告", MessageBoxButton.OK,
  301. MessageBoxImage.Warning);
  302. }
  303. }
  304. private void SrcImage_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  305. {
  306. var image = sender as Image;
  307. if (image == null) return;
  308. var dataContext = image.DataContext as PatchDetailItem;
  309. if (dataContext == null) return;
  310. //var dialog = new ImageViewerWindow(dataContext.SourceImagePath)
  311. if (!File.Exists(dataContext.SrcImage)) return;
  312. var dialog = new imgWindow(dataContext.SrcImage)
  313. {
  314. Owner = Application.Current.MainWindow
  315. };
  316. dialog.Show();
  317. }
  318. private void DstImage_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  319. {
  320. var image = sender as Image;
  321. if (image == null) return;
  322. var dataContext = image.DataContext as PatchDetailItem;
  323. if (dataContext == null) return;
  324. //var dialog = new ImageViewerWindow(dataContext.SourceImagePath)
  325. if (!File.Exists(dataContext.DstImage)) return;
  326. var dialog = new imgWindow(dataContext.DstImage)
  327. {
  328. Owner = Application.Current.MainWindow
  329. };
  330. dialog.Show();
  331. }
  332. public void NextPage()
  333. {
  334. if (PatchDetailPage.PageNumber < PatchDetailPage.PageCount)
  335. {
  336. PatchDetailPage.PageNumber += 1;
  337. LoadPatchDetailItemList(true);
  338. }
  339. }
  340. public void PrePage()
  341. {
  342. if (PatchDetailPage.PageNumber > 1)
  343. {
  344. PatchDetailPage.PageNumber -= 1;
  345. LoadPatchDetailItemList(true);
  346. }
  347. }
  348. public void FirstPage()
  349. {
  350. if (PatchDetailPage.PageNumber > 1)
  351. {
  352. PatchDetailPage.PageNumber = 1;
  353. LoadPatchDetailItemList(true);
  354. }
  355. }
  356. public void LastPage()
  357. {
  358. if (PatchDetailPage.PageNumber < PatchDetailPage.PageCount)
  359. {
  360. PatchDetailPage.PageNumber = PatchDetailPage.PageCount;
  361. LoadPatchDetailItemList(true);
  362. }
  363. }
  364. public void SpeciPage(int pageNumber)
  365. {
  366. if (pageNumber != PatchDetailPage.PageNumber &&
  367. pageNumber > 0 && pageNumber <= PatchDetailPage.PageCount)
  368. {
  369. PatchDetailPage.PageNumber = pageNumber;
  370. LoadPatchDetailItemList(true);
  371. }
  372. }
  373. private bool IsProcessingTask = false;
  374. public async Task<bool> StartPatchTask()
  375. {
  376. if (CurPatchItem == null) return false;
  377. int taskCount = await GetTaskCount();
  378. if(taskCount == 0)
  379. {
  380. MessageBox.Show(Application.Current.MainWindow, "没有任务可执行。", "提示",
  381. MessageBoxButton.OK, MessageBoxImage.Information);
  382. return false;
  383. }
  384. //先查询是否有需要识别的任务
  385. PatchTaskDlg patchTaskDlg = new PatchTaskDlg()
  386. {
  387. Owner = Application.Current.MainWindow,
  388. WindowStartupLocation = WindowStartupLocation.CenterOwner
  389. };
  390. patchTaskDlg.OnStopTask += PatchTaskDlg_OnStopTask;
  391. patchTaskDlg.Show();
  392. Application.Current.MainWindow.IsEnabled = false;
  393. try
  394. {
  395. IsProcessingTask = true;
  396. int runCount = 0;
  397. await Task.Run(() =>
  398. {
  399. //查询任务
  400. List<TPatchDetail> patchDetails = DBPatch.GetPatchDetailsWithRunFlagZero(CurPatchItem.PatchId);
  401. for(int i = 0; i < patchDetails.Count; i++)
  402. {
  403. if (!IsProcessingTask)
  404. {
  405. return;
  406. }
  407. FaRun faRun = new FaRun();
  408. ResultModel resultModel = null;
  409. try
  410. {
  411. resultModel = faRun.StartRecognition(patchDetails[i]);
  412. }
  413. catch(Exception ex)
  414. {
  415. Console.WriteLine(ex.Message);
  416. }
  417. if (resultModel == null) continue;
  418. patchDetails[i].SetResult(resultModel);
  419. bool blUpdate = DBPatch.UpdatePatchDetailWithResult(patchDetails[i]);
  420. //修改下一条记录的最近一次正确值(判断下一条数据的站点与本站点相同)
  421. if( i + 1 < patchDetails.Count && patchDetails[i + 1].StationId == patchDetails[i].StationId)
  422. {
  423. patchDetails[i + 1].LastCompress = resultModel.CompressIndex;
  424. if (patchDetails[i].IsGoodResult())
  425. {
  426. patchDetails[i+1].LatestValue = (long)resultModel.FinalValue;
  427. patchDetails[i+1].LatestComplete = (long)resultModel.CompleteValue;
  428. patchDetails[i+1].LatestTime = patchDetails[i].SampleTime;
  429. }
  430. else
  431. {
  432. patchDetails[i+1].LatestValue = patchDetails[i].LatestValue;
  433. patchDetails[i+1].LatestComplete = patchDetails[i].LatestComplete;
  434. patchDetails[i + 1].LatestTime = patchDetails[i].LatestTime;
  435. }
  436. //更新改变了Latest的数据
  437. if (DBPatch.UpdatePatchDetails_Latest(patchDetails[i + 1]))
  438. {
  439. foreach (PatchDetailItem detailItem in PatchDetailItemList)
  440. {
  441. if (detailItem.PatchDetailId == patchDetails[i + 1].PatchDetailId)
  442. {
  443. ObjectHelper.CopyMatchingFields(patchDetails[i + 1], detailItem);
  444. break;
  445. }
  446. }//foreach
  447. }
  448. }//i+1
  449. if (blUpdate)
  450. {
  451. runCount++;
  452. }
  453. //根据结果更新表内容,暂且模拟
  454. //Thread.Sleep(300);
  455. Application.Current.Dispatcher.Invoke(() =>
  456. {
  457. patchTaskDlg.UpdateProgress(i + 1, taskCount);
  458. //更新背后的数据
  459. if (blUpdate)
  460. {
  461. //如果界面中存在本条数据,则更新。意义不大
  462. foreach (PatchDetailItem detailItem in PatchDetailItemList)
  463. {
  464. if(detailItem.PatchDetailId == patchDetails[i].PatchDetailId)
  465. {
  466. ObjectHelper.CopyMatchingFields(patchDetails[i], detailItem);
  467. break;
  468. }
  469. }//foreach
  470. }//if
  471. });
  472. //Thread.Sleep(3000);
  473. }//for i
  474. });
  475. return runCount > 0;
  476. }
  477. catch(Exception ex)
  478. {
  479. MessageBox.Show(Application.Current.MainWindow, $"执行批量识别任务:{ex.Message}", "错误",
  480. MessageBoxButton.OK, MessageBoxImage.Error);
  481. return false;
  482. }
  483. finally
  484. {
  485. // 执行完毕后恢复主界面交互
  486. Application.Current.MainWindow.IsEnabled = true;
  487. patchTaskDlg.Close();
  488. }
  489. }
  490. private void PatchTaskDlg_OnStopTask()
  491. {
  492. IsProcessingTask = false;
  493. //throw new NotImplementedException();
  494. }
  495. //获取任务数量
  496. private async Task<int> GetTaskCount()
  497. {
  498. if (CurPatchItem == null) return 0;
  499. string titleInfo = "正在获取任务数量,请稍后...";
  500. WaitWindow waitWindow = new WaitWindow(titleInfo)
  501. {
  502. Owner = Application.Current.MainWindow,
  503. WindowStartupLocation = WindowStartupLocation.CenterOwner
  504. };
  505. waitWindow.Show();
  506. try
  507. {
  508. int taskCount = await Task.Run(() =>
  509. {
  510. return DBPatch.GetPatchDetailsCountWithRunFlagZero(CurPatchItem.PatchId);
  511. });
  512. return taskCount;
  513. }
  514. catch (Exception ex)
  515. {
  516. MessageBox.Show(Application.Current.MainWindow, $"获取任务数量:{ex.Message}", "错误",
  517. MessageBoxButton.OK, MessageBoxImage.Error);
  518. return 0;
  519. }
  520. finally
  521. {
  522. waitWindow.Close();
  523. }
  524. }
  525. private void BtnLogViewer_Click(object sender, RoutedEventArgs e)
  526. {
  527. Button button = sender as Button;
  528. if (button == null) return;
  529. DataGridRow row = FindAncestor<DataGridRow>(button);
  530. if (row == null) return;
  531. //获取当前行绑定的数据项
  532. PatchDetailItem selectedItem = row.Item as PatchDetailItem;
  533. ShowLogViewer(selectedItem);
  534. }
  535. private void ShowLogViewer(PatchDetailItem selectedItem)
  536. {
  537. if (selectedItem.LogPath != null && File.Exists(selectedItem.LogPath))
  538. {
  539. //LogViewerWindow dialog = new LogViewerWindow(selectedItem.DstImage, selectedItem.LogPath)
  540. var dialog = new LogViewerWindow(selectedItem)
  541. {
  542. Owner = Application.Current.MainWindow,
  543. WindowStartupLocation = WindowStartupLocation.CenterOwner
  544. };
  545. //dialog.ShowDialog();
  546. dialog.Show();
  547. }
  548. }
  549. private void BtnDelDetailItem_Click(object sender, RoutedEventArgs e)
  550. {
  551. //删除选中项
  552. Button button = sender as Button;
  553. if (button == null) return;
  554. DataGridRow row = FindAncestor<DataGridRow>(button);
  555. if (row == null) return;
  556. //获取当前行绑定的数据项
  557. PatchDetailItem selectedItem = row.Item as PatchDetailItem;
  558. DeleteSelectedItem(selectedItem);
  559. }
  560. private async void DeleteSelectedItem(PatchDetailItem selectedItem)
  561. {
  562. if (selectedItem == null) return;
  563. MessageBoxResult result = MessageBox.Show("确定要删除此条目吗?", "确认删除", MessageBoxButton.YesNo, MessageBoxImage.Question);
  564. if (result != MessageBoxResult.Yes) return;
  565. string titleInfo = "正在删除,请稍后...";
  566. WaitWindow waitWindow = new WaitWindow(titleInfo)
  567. {
  568. Owner = Application.Current.MainWindow,
  569. WindowStartupLocation = WindowStartupLocation.CenterOwner
  570. };
  571. waitWindow.Show();
  572. try
  573. {
  574. bool deleteSuccess = false;
  575. await Task.Run(() =>
  576. {
  577. deleteSuccess = DBPatch.Delete_TPatchDetail_TStandDetail_ByStand(selectedItem.StandDetailId);
  578. //deleteSuccess = DBPatch.DeleteTPatchDetailById(selectedItem.PatchDetailId);
  579. });
  580. if (deleteSuccess)
  581. {
  582. Application.Current.Dispatcher.Invoke(() =>
  583. {
  584. // 从数据源中移除该条目
  585. int selectedIndex = PatchDetailItemList.IndexOf(selectedItem);
  586. //PatchDetailItemList.Remove(selectedItem); 改为从新加载页面
  587. SelectedPatchDetailItem = null;
  588. OnRefreshPatchItem?.Invoke(selectedItem.PatchId);
  589. OnDeleteStandDetail?.Invoke(selectedItem.StandDetailId);
  590. //重新加载数据
  591. LoadPatchDetailItemList(false);
  592. //if (PatchDetailItemList.Count > selectedIndex)
  593. //{
  594. // dgPatchDetail.ScrollIntoView(dgPatchDetail.Items[selectedIndex]);
  595. //}
  596. });
  597. }
  598. }
  599. catch (Exception ex)
  600. {
  601. MessageBox.Show(Application.Current.MainWindow, $"删除失败:{ex.Message}", "错误",
  602. MessageBoxButton.OK, MessageBoxImage.Error);
  603. }
  604. finally
  605. {
  606. waitWindow.Close();
  607. }
  608. }
  609. public static T FindAncestor<T>(DependencyObject dependencyObject) where T : DependencyObject
  610. {
  611. var parent = VisualTreeHelper.GetParent(dependencyObject);
  612. if (parent == null) return null;
  613. var parentT = parent as T;
  614. return parentT ?? FindAncestor<T>(parent);
  615. }
  616. private void MiViewLog_Click(object sender, RoutedEventArgs e)
  617. {
  618. if(SelectedPatchDetailItem != null)
  619. {
  620. ShowLogViewer(SelectedPatchDetailItem);
  621. }
  622. }
  623. private void MiDelteRow_Click(object sender, RoutedEventArgs e)
  624. {
  625. //获取当前行绑定的数据项
  626. if(SelectedPatchDetailItem != null)
  627. {
  628. DeleteSelectedItem(SelectedPatchDetailItem);
  629. }
  630. }
  631. private void BtnUpdateStandvalue_Click(object sender, RoutedEventArgs e)
  632. {
  633. Button button = sender as Button;
  634. if (button == null) return;
  635. DataGridRow row = FindAncestor<DataGridRow>(button);
  636. if (row == null) return;
  637. //获取当前行绑定的数据项
  638. var selectedItem = row.Item as PatchDetailItem;
  639. UpdateStandvalue(selectedItem);
  640. }
  641. private void MiUpdateStandvalue_Click(object sender, RoutedEventArgs e)
  642. {
  643. if (SelectedPatchDetailItem == null) return;
  644. UpdateStandvalue(SelectedPatchDetailItem);
  645. }
  646. private void MiAddMemo_Click(object sender, RoutedEventArgs e)
  647. {
  648. if (SelectedPatchDetailItem == null) return;
  649. AddMemo(SelectedPatchDetailItem);
  650. }
  651. private void AddMemo(PatchDetailItem detailItem)
  652. {
  653. if (detailItem == null) return;
  654. EditMemo editMemo = new EditMemo(detailItem.Memo)
  655. {
  656. Owner = Application.Current.MainWindow,
  657. WindowStartupLocation = WindowStartupLocation.CenterOwner
  658. };
  659. if (editMemo.ShowDialog() == true)
  660. {
  661. string memo = editMemo.Memo;
  662. if (DBPatch.UpdatePatchDetailMemo(detailItem.PatchDetailId, memo))
  663. {
  664. detailItem.Memo = memo;
  665. }
  666. }
  667. }
  668. private void Memo_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  669. {
  670. if (e.ClickCount == 2)
  671. {
  672. if (SelectedPatchDetailItem == null) return;
  673. AddMemo(SelectedPatchDetailItem);
  674. }
  675. }
  676. private void FaRun_OnAiRealLogInfo(object sender, AiRealLogEventArgs e)
  677. {
  678. Console.Write(e.mLogInfo);
  679. }
  680. private void MiRecong_Click(object sender, RoutedEventArgs e)
  681. {
  682. if (SelectedPatchDetailItem == null) return;
  683. RecongPatchDetail(SelectedPatchDetailItem);
  684. }
  685. private async void RecongPatchDetail(PatchDetailItem patchDetailItem)
  686. {
  687. string jpgFile = patchDetailItem.SrcImage;
  688. if (!File.Exists(jpgFile))
  689. {
  690. MessageBox.Show(Application.Current.MainWindow, $"文件:{jpgFile}不存在!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
  691. return;
  692. }
  693. bool blRun = await RunAI(patchDetailItem);
  694. if (blRun)
  695. {
  696. //MessageBox.Show(Application.Current.MainWindow, "识别成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
  697. }
  698. else
  699. {
  700. MessageBox.Show(Application.Current.MainWindow, "识别失败!", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  701. }
  702. }
  703. private async Task<bool> RunAI(PatchDetailItem patchDetailItem)
  704. {
  705. FaRun faRun = new FaRun();
  706. faRun.OnAiRealLogInfo += FaRun_OnAiRealLogInfo;
  707. string titleInfo = "正在识别,请稍后...";
  708. WaitWindow waitWindow = new WaitWindow(titleInfo)
  709. {
  710. Owner = Application.Current.MainWindow,
  711. WindowStartupLocation = WindowStartupLocation.CenterOwner
  712. };
  713. waitWindow.Show();
  714. try
  715. {
  716. TPatchDetail newPatchDetail = null;
  717. bool blRun = await Task.Run(() =>
  718. {
  719. try
  720. {
  721. ResultModel resultModel = null;
  722. try
  723. {
  724. resultModel = faRun.StartRecognition(patchDetailItem);
  725. }
  726. catch (Exception ex)
  727. {
  728. Console.WriteLine(ex.Message);
  729. }
  730. if (resultModel == null) return false;
  731. newPatchDetail = new TPatchDetail(patchDetailItem, resultModel);
  732. //更新数据
  733. bool blUpdate = DBPatch.UpdatePatchDetailWithResult(newPatchDetail);
  734. return blUpdate;
  735. }
  736. catch (Exception ex)
  737. {
  738. Application.Current.Dispatcher.Invoke(() =>
  739. {
  740. MessageBox.Show(Application.Current.MainWindow, $"{ex.Message}", "错误",
  741. MessageBoxButton.OK, MessageBoxImage.Error);
  742. });
  743. return false;
  744. }
  745. });
  746. //------
  747. //在主线程中更新DataGrid的Row数据
  748. if (blRun && newPatchDetail != null)
  749. {
  750. ObjectHelper.CopyMatchingFields(newPatchDetail, patchDetailItem);
  751. }
  752. return blRun;
  753. }
  754. catch (Exception ex)
  755. {
  756. MessageBox.Show(Application.Current.MainWindow, $"识别[{patchDetailItem.SrcImage}]时出错:{ex.Message}", "错误",
  757. MessageBoxButton.OK, MessageBoxImage.Error);
  758. return false;
  759. }
  760. finally
  761. {
  762. waitWindow.Close();
  763. }
  764. }
  765. ////-------------以下代码被作废,暂不使用此方法-------------------
  766. //private PatchPrgDialog PatchPrgDialog; // 用于弹出进度对话框
  767. //public event Action<int,int> OnProcessingProgressChanged; // 用于通知进度
  768. //public event Action OnProcessingCompleted; // 用于通知完成
  769. //public event Action OnProcessingStopped; // 用于通知停止
  770. //private BackgroundWorker worker;
  771. ////private bool isProcessing;
  772. //private bool cancelRequested;
  773. //private int TotalImages;
  774. ////开始批量识别任务
  775. //public void StartPatchTask2()
  776. //{
  777. // worker = new BackgroundWorker();
  778. // worker.DoWork += Worker_DoWork;
  779. // worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
  780. // worker.ProgressChanged += Worker_ProgressChanged;
  781. // worker.WorkerReportsProgress = true;
  782. // worker.WorkerSupportsCancellation = true;
  783. // PatchPrgDialog = new PatchPrgDialog(this); // 传递 UserControl 实例给对话框
  784. // PatchPrgDialog.StartProcessing();
  785. //}
  786. //// 启动处理
  787. //public void StartProcessing()
  788. //{
  789. // //isProcessing = true;
  790. // cancelRequested = false;
  791. // worker.RunWorkerAsync();
  792. //}
  793. //// 停止处理
  794. //public void StopProcessing()
  795. //{
  796. // cancelRequested = true;
  797. // worker.CancelAsync();
  798. //}
  799. //// 执行后台处理任务
  800. //private void Worker_DoWork(object sender, DoWorkEventArgs e)
  801. //{
  802. // //int totalImages = 100; // 假设有100张图片要处理
  803. // TotalImages = 100;
  804. // for (int i = 1; i <= TotalImages; i++)
  805. // {
  806. // if (cancelRequested)
  807. // {
  808. // e.Cancel = true;
  809. // break;
  810. // }
  811. // // 模拟处理图片
  812. // Thread.Sleep(1000); // 这里模拟了图片处理的延迟
  813. // // 更新进度
  814. // //worker.ReportProgress((i * 100) / totalImages);
  815. // worker.ReportProgress(i);
  816. // }
  817. //}
  818. //// 更新进度条
  819. //private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
  820. //{
  821. // //progressBar.Value = e.ProgressPercentage;
  822. // OnProcessingProgressChanged?.Invoke(e.ProgressPercentage,TotalImages);
  823. //}
  824. //// 处理完成或被取消
  825. //private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  826. //{
  827. // if (e.Cancelled)
  828. // {
  829. // OnProcessingStopped?.Invoke();
  830. // }
  831. // else
  832. // {
  833. // OnProcessingCompleted?.Invoke();
  834. // }
  835. //}
  836. //-----------------------------------------------------------------------------------
  837. }
  838. // 自定义事件参数类
  839. public class PatchDetailItemChangedEventArgs : EventArgs
  840. {
  841. public PatchDetailItem SelectedPatchDetailItem { get; }
  842. public PatchDetailItemChangedEventArgs(PatchDetailItem selectedData)
  843. {
  844. SelectedPatchDetailItem = selectedData;
  845. }
  846. }
  847. }