using MeterVision.Config; using MeterVision.db; using MeterVision.Dlg; using MeterVision.FreeAi; using MeterVision.Helper; using MeterVision.model; using MeterVision.Util; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace MeterVision.Patch { /// /// UCPatchGrid.xaml 的交互逻辑 /// public partial class UCPatchGrid : UserControl, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private SemaphoreSlim _loadLock = new SemaphoreSlim(1, 1); private bool _isLoading = false; //定义任务详情数据源 public BulkObservableCollection PatchDetailItemList { get; set; } // 定义事件,用于通知外部组件选中项已更改 public event EventHandler OnSelectedPatchDetailItemChanged; public event Action OnRefreshPatchItem; //删除标准模板明细事件 public static event Action OnDeleteStandDetail; //修改标准模板值事件 public static event Action OnUpdateStandValue; private PatchDetailItem _selectedPatchDetailItem; //定义SelectedDataItem属性,并在值变化时触发事件 public PatchDetailItem SelectedPatchDetailItem { get => _selectedPatchDetailItem; set { if (_selectedPatchDetailItem != value) { _selectedPatchDetailItem = value; OnPropertyChanged(nameof(SelectedPatchDetailItem)); OnSelectedPatchDetailItemChanged?.Invoke(this, new PatchDetailItemChangedEventArgs(value)); } } } private PatchItem _curPatchItem; private PatchItem CurPatchItem { get => _curPatchItem; set { if (_curPatchItem != value) { _curPatchItem = value; //PatchDetailPage.InitDefaulValue(mConfigItem.PatchPageSize); //PatchDetailPage.InitDefaulValue(); //LoadPatchDetailItemList(); } } } //此属性只在函数内部调用 private VPatchStation _curStationItem; private VPatchStation CurStationItem { get => _curStationItem; set { if (_curStationItem != value) { _curStationItem = value; //PatchDetailPage.InitDefaulValue(mConfigItem.StandPageSize); //LoadStandDetailItemList(); } } } private PatchFindType _selectedPatchFindType; private PatchFindType SelectedPatchFindType { get => _selectedPatchFindType; set { if (_selectedPatchFindType != value) { _selectedPatchFindType = value; //OnPropertyChanged(nameof(SelectedPatchFindType)); //PatchDetailPage.InitDefaulValue(); } } } //改变PatchItem或PatchFinType public void ChangePatchItemOrFinType(PatchItem curPatchItem,VPatchStation curStationItem,PatchFindType patchFindType) { //bool blPatchItemChanged = false; //bool blPatchFindTypeChanged = false; //bool blStationChanged = false; //判断是否数据发生变化 if(curPatchItem != _curPatchItem) { CurPatchItem = curPatchItem; //blPatchItemChanged = true; } if(curStationItem != _curStationItem) { CurStationItem = curStationItem; //blStationChanged = true; } if(patchFindType != _selectedPatchFindType) { SelectedPatchFindType = patchFindType; //blPatchFindTypeChanged = true; } //if(blPatchItemChanged || blPatchFindTypeChanged || blStationChanged) { PatchDetailPage.InitDefaulValue(); LoadPatchDetailItemList(true); } } public CfginiItem mConfigItem { get; set; } public PageModel PatchDetailPage { get; set; } private int _totalRecord; public int TotalRecords { get => _totalRecord; set { if (_totalRecord != value) { _totalRecord = value; OnPropertyChanged(nameof(TotalRecords)); } } } public UCPatchGrid() { InitializeComponent(); PatchDetailItemList = new BulkObservableCollection(); dgPatchDetail.ItemsSource = PatchDetailItemList; mConfigItem = CfginiItem.GetConfigItem(); PatchDetailPage = new PageModel { PageSize = mConfigItem.PageSize3, //mConfigItem.PatchPageSize, PageNumber = 1 }; //mConfigItem.OnPatchPageSizeChanged += MConfigItem_OnPatchPageSizeChanged; //mConfigItem.OnPatchPageSizeChanged += MConfigItem_OnPatchPageSizeChanged; mConfigItem.OnPageSize3Changed += MConfigItem_OnPageSize3Changed; this.DataContext = this; } private void MConfigItem_OnPageSize3Changed(int pageSize3) { if (_isLoading) return; try { _isLoading = true; //throw new NotImplementedException(); PatchDetailPage.InitDefaulValue(pageSize3); LoadPatchDetailItemList(true); } catch { } finally { _isLoading = false; } } //private void MConfigItem_OnPatchPageSizeChanged(int pageSize) //{ // PatchDetailPage.InitDefaulValue(pageSize); // LoadPatchDetailItemList(true); //} //private void MConfigItem_OnPatchPageSizeChanged(object sender, PageSizeChangedEventArgs e) //{ // PatchDetailPage.InitDefaulValue(e.PageSize); // LoadPatchDetailItemList(true); //} private async void LoadPatchDetailItemList(bool scrollTop) { if (!await _loadLock.WaitAsync(0)) return; // 如果已有任务在执行,则直接返回 try { PatchDetailItemList.Clear(); //if (CurPatchItem != null ) if (CurStationItem != null) { try { var result = await Task.Run(() => { //数据库查询 //return DBPatch.GetPagedPatchDetails( // PatchDetailPage.PageNumber, PatchDetailPage.PageSize, CurPatchItem.PatchId); string stationId = CurStationItem == null ? "" : CurStationItem.StationId; PatchFindModel findModel = new PatchFindModel(PatchDetailPage.PageNumber, PatchDetailPage.PageSize, CurPatchItem.PatchId, stationId, SelectedPatchFindType); return DBPatch.GetPagedPatchDetails(findModel); }); //var result = DBPatch.GetPagedPatchDetails(findModel); //更新分页信息 TotalRecords = result.Item1; PatchDetailPage.PageCount = result.Item2; List patchDetails = result.Item3; //更新数据需要在主线中进行 //await Application.Current.Dispatcher.BeginInvoke(new Action(() => //{ //int index = 0; //foreach (TPatchDetail patchDetail in patchDetails) //{ // index++; // PatchDetailItem item = new PatchDetailItem(patchDetail); // item.Index = index + ((PatchDetailPage.PageNumber - 1) * PatchDetailPage.PageSize); // PatchDetailItemList.Add(item); //}//foreach var patchDetailItems = patchDetails.Select((patchDetail, i) => new PatchDetailItem(patchDetail) { Index = (PatchDetailPage.PageNumber - 1) * PatchDetailPage.PageSize + i + 1 }).ToList(); PatchDetailItemList.AddRange(patchDetailItems); //SelectedPatchDetailItem = null; if (PatchDetailItemList.Count > 0 && scrollTop) { //await Task.Delay(50); //dgPatchDetail.UpdateLayout(); //await Task.Yield(); //await Dispatcher.InvokeAsync(() => //{ // dgPatchDetail.ScrollIntoView(dgPatchDetail.Items[0]); //}); var scrollViewer = GetScrollViewer(dgPatchDetail); scrollViewer?.ScrollToTop(); } ///})); } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"d加载数据时发生错误:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); //return false; } } //if (PatchDetailItemList.Count > 0) //{ // SelectedPatchDetailItem = PatchDetailItemList[0]; //} //else //{ // SelectedPatchDetailItem = null; //} } catch { } finally { _loadLock.Release(); } } private void StandResultTextBlock_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // 检查是否是双击 if (e.ClickCount == 2) { // 获取当前行的数据上下文 var textBlock = sender as TextBlock; if (textBlock == null) return; var dataContext = textBlock.DataContext as PatchDetailItem; // 替换为你的数据类型 if (dataContext == null) return; SelectedPatchDetailItem = dataContext; StandValueModel standValueModel = new StandValueModel(dataContext); var dialog = new EditStandValueDlg(standValueModel) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; //if(dialog.ShowDialog() == true) //{ // UpdatePatchDetailStandValue(dataContext, standValueModel); //}//if showDialog dialog.OnEditStandValue += (value) => { UpdatePatchDetailStandValue(dataContext, standValueModel); }; dialog.Show(); }//e.clickCount } private void UpdateStandvalue(PatchDetailItem detailItem) { StandValueModel standValueModel = new StandValueModel(detailItem); var dialog = new EditStandValueDlg(standValueModel) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; //if (dialog.ShowDialog() == true) //{ // UpdatePatchDetailStandValue(detailItem, standValueModel); //}//if showDialog dialog.OnEditStandValue += (value) => { UpdatePatchDetailStandValue(detailItem, standValueModel); }; dialog.Show(); } private void UpdatePatchDetailStandValue(PatchDetailItem detailItem, StandValueModel standValueModel) { try { //修改数据库 //判断detailItem中的FinalValue与标准值是否相等 int equalFlag = 0; if (string.IsNullOrWhiteSpace(standValueModel.StandValue)) { equalFlag = 3; } else { if (double.TryParse(standValueModel.StandValue, out double dStandValue)) { equalFlag = detailItem.GetEqualFlag(dStandValue, detailItem.FinalValue); } } bool updateStandValue1 = DBPatch.UpdatePatchDetailStandValue(detailItem.PatchDetailId, standValueModel.StandValue,equalFlag); bool updateStandValue2 = DBStand.UpdateStandDetailStandValue(detailItem.SrcImage, standValueModel.StandValue); if (updateStandValue1 && updateStandValue2) { detailItem.StandValue = standValueModel.StandValue; detailItem.EqualFlag = equalFlag; //MessageBox.Show(Application.Current.MainWindow, "修改标准值完成。", "提示", MessageBoxButton.OK, // MessageBoxImage.Information); //应该更新目录内容 OnRefreshPatchItem?.Invoke(detailItem.PatchId); OnUpdateStandValue?.Invoke(detailItem.StandDetailId, detailItem.StandValue); } else { MessageBox.Show(Application.Current.MainWindow, "修改标准值失败。", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); } } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"修改标准值错误:{ex.Message}!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); } } private void SrcImage_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var image = sender as Image; if (image == null) return; var dataContext = image.DataContext as PatchDetailItem; if (dataContext == null) return; //var dialog = new ImageViewerWindow(dataContext.SourceImagePath) if (!File.Exists(dataContext.SrcImage)) return; var dialog = new imgWindow(dataContext.SrcImage) { Owner = Application.Current.MainWindow }; dialog.Show(); } private void DstImage_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var image = sender as Image; if (image == null) return; var dataContext = image.DataContext as PatchDetailItem; if (dataContext == null) return; //var dialog = new ImageViewerWindow(dataContext.SourceImagePath) if (!File.Exists(dataContext.DstImage)) return; var dialog = new imgWindow(dataContext.DstImage) { Owner = Application.Current.MainWindow }; dialog.Show(); } public void NextPage() { //if (!await _loadLock.WaitAsync(0)) return; // 如果已有任务在执行,则直接返回 if (_isLoading) return; // 如果正在加载,直接返回 try { _isLoading = true; if (PatchDetailPage.PageNumber < PatchDetailPage.PageCount) { PatchDetailPage.PageNumber += 1; LoadPatchDetailItemList(true); } } catch { } finally { _isLoading = false; } } public void PrePage() { if (_isLoading) return; // 如果正在加载,直接返回 try { _isLoading = true; if (PatchDetailPage.PageNumber > 1) { PatchDetailPage.PageNumber -= 1; LoadPatchDetailItemList(true); } } catch { } finally { _isLoading = false; } } public void FirstPage() { if (_isLoading) return; // 如果正在加载,直接返回 try { _isLoading = true; if (PatchDetailPage.PageNumber > 1) { PatchDetailPage.PageNumber = 1; LoadPatchDetailItemList(true); } } catch { } finally { _isLoading = false; } } public void LastPage() { if (_isLoading) return; // 如果正在加载,直接返回 try { _isLoading = true; if (PatchDetailPage.PageNumber < PatchDetailPage.PageCount) { PatchDetailPage.PageNumber = PatchDetailPage.PageCount; LoadPatchDetailItemList(true); } } catch { } finally { _isLoading = false; } } public void SpeciPage(int pageNumber) { if (_isLoading) return; // 如果正在加载,直接返回 try { _isLoading = true; if (pageNumber != PatchDetailPage.PageNumber && pageNumber > 0 && pageNumber <= PatchDetailPage.PageCount) { PatchDetailPage.PageNumber = pageNumber; LoadPatchDetailItemList(true); } } catch { } finally { _isLoading = false; } } private bool IsProcessingTask = false; public async Task StartPatchTask() { if (CurPatchItem == null) return false; int taskCount = await GetTaskCount(); if(taskCount == 0) { MessageBox.Show(Application.Current.MainWindow, "没有任务可执行。", "提示", MessageBoxButton.OK, MessageBoxImage.Information); return false; } //先查询是否有需要识别的任务 PatchTaskDlg patchTaskDlg = new PatchTaskDlg() { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; patchTaskDlg.OnStopTask += PatchTaskDlg_OnStopTask; patchTaskDlg.Show(); Application.Current.MainWindow.IsEnabled = false; try { IsProcessingTask = true; int runCount = 0; await Task.Run(() => { string stationId = CurStationItem == null ? "" : CurStationItem.StationId; //查询任务 List patchDetails = DBPatch.GetPatchDetailsWithRunFlag(CurPatchItem.PatchId,stationId,0); for(int i = 0; i < patchDetails.Count; i++) { if (!IsProcessingTask) { return; } FaRun faRun = new FaRun(); faRun.OnAiRealLogInfo += (sender,e) => { Console.WriteLine(e.mLogInfo); }; ResultModel resultModel = null; try { resultModel = faRun.StartRecognition(patchDetails[i]); } catch(Exception ex) { Console.WriteLine(ex.Message); } if (resultModel == null) continue; patchDetails[i].SetResult(resultModel); bool blUpdate = DBPatch.UpdatePatchDetailWithResult(patchDetails[i]); //修改下一条记录的最近一次正确值(判断下一条数据的站点与本站点相同) if( i + 1 < patchDetails.Count && patchDetails[i + 1].StationId == patchDetails[i].StationId) { if (patchDetails[i + 1].LatestValue == -1) { patchDetails[i + 1].LastCompress = resultModel.CompressIndex; if (patchDetails[i].IsGoodResult()) { patchDetails[i + 1].LatestValue = (long)resultModel.FinalValue; patchDetails[i + 1].LatestComplete = (long)resultModel.CompleteValue; patchDetails[i + 1].LatestTime = patchDetails[i].SampleTime; } else { patchDetails[i + 1].LatestValue = patchDetails[i].LatestValue; patchDetails[i + 1].LatestComplete = patchDetails[i].LatestComplete; patchDetails[i + 1].LatestTime = patchDetails[i].LatestTime; } } //根据当前的识别结果修改下一条的表盘、数字域或首尾坐标域 if(string.IsNullOrEmpty(patchDetails[i + 1].MeterRegion) && patchDetails[i+1].MeterType == patchDetails[i].MeterType) { patchDetails[i + 1].MeterRegion = resultModel.MeterRegions; patchDetails[i + 1].FeatureRegion = resultModel.FeatureRegions; } //更新改变了Latest的数据 if (DBPatch.UpdatePatchDetails_Latest(patchDetails[i + 1])) { foreach (PatchDetailItem detailItem in PatchDetailItemList) { if (detailItem.PatchDetailId == patchDetails[i + 1].PatchDetailId) { ObjectHelper.CopyMatchingFields(patchDetails[i + 1], detailItem); break; } }//foreach } }//i+1 if (blUpdate) { runCount++; } //根据结果更新表内容,暂且模拟 //Thread.Sleep(300); //这里需要同步 //Application.Current.Dispatcher.Invoke(() => //{ patchTaskDlg.UpdateProgress(i + 1, taskCount); ////更新背后的数据 if (blUpdate) { //如果界面中存在本条数据,则更新。意义不大 foreach (PatchDetailItem detailItem in PatchDetailItemList) { if (detailItem.PatchDetailId == patchDetails[i].PatchDetailId) { ObjectHelper.CopyMatchingFields(patchDetails[i], detailItem); break; } }//foreach }//if //}); //Thread.Sleep(3000); }//for i }); return runCount > 0; } catch(Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"执行批量识别任务:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); return false; } finally { // 执行完毕后恢复主界面交互 Application.Current.MainWindow.IsEnabled = true; patchTaskDlg.Close(); } } //如果是存在已执行的任务,恢复未执行任务的数据状态 public async Task ResetPatchTask() { if (CurPatchItem == null) return false; string titleInfo = "正在恢复为任务未执行的状态,请稍后..."; WaitWindow waitWindow = new WaitWindow(titleInfo) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; waitWindow.Show(); try { List patchDetails = null; bool blUpdate = false; await Task.Run(() => { string stationId = CurStationItem == null ? "" : CurStationItem.StationId; //查询数据 //patchDetails = DBPatch.GetPatchDetailsWithRunFlag(CurPatchItem.PatchId, stationId,1); patchDetails = DBPatch.GetPatchDetailsWithRunFlag_StandDetal(CurPatchItem.PatchId, stationId, 1); foreach (var patchDetail in patchDetails) { //删除目标图像及识别日志 try { if (File.Exists(patchDetail.DstImage)) { File.Delete(patchDetail.DstImage); } if (File.Exists(patchDetail.LogPath)) { File.Delete(patchDetail.LogPath); } } catch { } patchDetail.ResetRunValue(); //恢复初始值 //查找原始t_stand_detail中表盘等坐标 } if (patchDetails.Count > 0) { blUpdate = DBPatch.UpdatePatchDetails(patchDetails); } }); if (blUpdate && patchDetails != null) { foreach (PatchDetailItem detailItem in PatchDetailItemList) { var findItem = patchDetails.Find((a) => a.PatchDetailId == detailItem.PatchDetailId); if(findItem!= null) { ObjectHelper.CopyMatchingFields(findItem, detailItem); } }//foreach } return true; } catch(Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); return false; } finally { waitWindow.Close(); } } private void PatchTaskDlg_OnStopTask() { IsProcessingTask = false; //throw new NotImplementedException(); } //获取任务数量 private async Task GetTaskCount() { if (CurPatchItem == null) return 0; string titleInfo = "正在获取任务数量,请稍后..."; WaitWindow waitWindow = new WaitWindow(titleInfo) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; waitWindow.Show(); try { int taskCount = await Task.Run(() => { string stationId = CurStationItem == null ? "" : CurStationItem.StationId; return DBPatch.GetPatchDetailsCountWithRunFlagZero(CurPatchItem.PatchId,stationId); }); return taskCount; } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"获取任务数量:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); return 0; } finally { waitWindow.Close(); } } private void BtnLogViewer_Click(object sender, RoutedEventArgs e) { Button button = sender as Button; if (button == null) return; DataGridRow row = FindAncestor(button); if (row == null) return; //获取当前行绑定的数据项 PatchDetailItem selectedItem = row.Item as PatchDetailItem; ShowLogViewer(selectedItem); } private void ShowLogViewer(PatchDetailItem selectedItem) { if (selectedItem.LogPath != null && File.Exists(selectedItem.LogPath)) { //LogViewerWindow dialog = new LogViewerWindow(selectedItem.DstImage, selectedItem.LogPath) var dialog = new LogViewerWindow(selectedItem) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; //dialog.ShowDialog(); dialog.Show(); } } private void BtnDelDetailItem_Click(object sender, RoutedEventArgs e) { //删除选中项 Button button = sender as Button; if (button == null) return; DataGridRow row = FindAncestor(button); if (row == null) return; //获取当前行绑定的数据项 PatchDetailItem selectedItem = row.Item as PatchDetailItem; DeleteSelectedItem(selectedItem); } private async void DeleteSelectedItem(PatchDetailItem selectedItem) { if (selectedItem == null) return; MessageBoxResult result = MessageBox.Show("确定要删除此条目吗?", "确认删除", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result != MessageBoxResult.Yes) return; string titleInfo = "正在删除,请稍后..."; WaitWindow waitWindow = new WaitWindow(titleInfo) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; waitWindow.Show(); try { bool deleteSuccess = false; await Task.Run(() => { deleteSuccess = DBPatch.Delete_TPatchDetail_TStandDetail_ByStand(selectedItem.StandDetailId); //deleteSuccess = DBPatch.DeleteTPatchDetailById(selectedItem.PatchDetailId); }); if (deleteSuccess) { //Application.Current.Dispatcher.Invoke(() => //{ // 从数据源中移除该条目 int selectedIndex = PatchDetailItemList.IndexOf(selectedItem); //PatchDetailItemList.Remove(selectedItem); 改为从新加载页面 SelectedPatchDetailItem = null; OnRefreshPatchItem?.Invoke(selectedItem.PatchId); OnDeleteStandDetail?.Invoke(selectedItem.StandDetailId); //重新加载数据 LoadPatchDetailItemList(false); //if (PatchDetailItemList.Count > selectedIndex) //{ // dgPatchDetail.ScrollIntoView(dgPatchDetail.Items[selectedIndex]); //} //}); } } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"删除失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } finally { waitWindow.Close(); } } public static T FindAncestor(DependencyObject dependencyObject) where T : DependencyObject { var parent = VisualTreeHelper.GetParent(dependencyObject); if (parent == null) return null; var parentT = parent as T; return parentT ?? FindAncestor(parent); } private void MiViewLog_Click(object sender, RoutedEventArgs e) { if(SelectedPatchDetailItem != null) { ShowLogViewer(SelectedPatchDetailItem); } } private void MiDelteRow_Click(object sender, RoutedEventArgs e) { //获取当前行绑定的数据项 if(SelectedPatchDetailItem != null) { DeleteSelectedItem(SelectedPatchDetailItem); } } private void BtnUpdateStandvalue_Click(object sender, RoutedEventArgs e) { Button button = sender as Button; if (button == null) return; DataGridRow row = FindAncestor(button); if (row == null) return; //获取当前行绑定的数据项 var selectedItem = row.Item as PatchDetailItem; UpdateStandvalue(selectedItem); } private void MiUpdateStandvalue_Click(object sender, RoutedEventArgs e) { if (SelectedPatchDetailItem == null) return; UpdateStandvalue(SelectedPatchDetailItem); } private void MiAddMemo_Click(object sender, RoutedEventArgs e) { if (SelectedPatchDetailItem == null) return; AddMemo(SelectedPatchDetailItem); } private void AddMemo(PatchDetailItem detailItem) { if (detailItem == null) return; EditMemo editMemo = new EditMemo(detailItem.Memo) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; if (editMemo.ShowDialog() == true) { string memo = editMemo.Memo; if (DBPatch.UpdatePatchDetailMemo(detailItem.PatchDetailId, memo)) { detailItem.Memo = memo; } } } private void Memo_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (e.ClickCount == 2) { if (SelectedPatchDetailItem == null) return; AddMemo(SelectedPatchDetailItem); } } private void FaRun_OnAiRealLogInfo(object sender, AiRealLogEventArgs e) { Console.Write(e.mLogInfo); } private void MiRecong_Click(object sender, RoutedEventArgs e) { if (SelectedPatchDetailItem == null) return; RecongPatchDetail(SelectedPatchDetailItem); } private async void RecongPatchDetail(PatchDetailItem patchDetailItem) { string jpgFile = patchDetailItem.SrcImage; if (!File.Exists(jpgFile)) { MessageBox.Show(Application.Current.MainWindow, $"文件:{jpgFile}不存在!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); return; } bool blRun = await RunAI(patchDetailItem); if (blRun) { //MessageBox.Show(Application.Current.MainWindow, "识别成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); } else { MessageBox.Show(Application.Current.MainWindow, "识别失败!", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } private async Task RunAI(PatchDetailItem patchDetailItem) { FaRun faRun = new FaRun(); faRun.OnAiRealLogInfo += FaRun_OnAiRealLogInfo; string titleInfo = "正在识别,请稍后..."; WaitWindow waitWindow = new WaitWindow(titleInfo) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; waitWindow.Show(); try { TPatchDetail newPatchDetail = null; bool blRun = await Task.Run(() => { try { ResultModel resultModel = null; try { resultModel = faRun.StartRecognition(patchDetailItem); } catch (Exception ex) { Console.WriteLine(ex.Message); } if (resultModel == null) return false; newPatchDetail = new TPatchDetail(patchDetailItem, resultModel); //更新数据 bool blUpdate = DBPatch.UpdatePatchDetailWithResult(newPatchDetail); return blUpdate; } catch (Exception ex) { Dispatcher.Invoke(() => { MessageBox.Show(Application.Current.MainWindow, $"{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); }); return false; } }); //------ //在主线程中更新DataGrid的Row数据 if (blRun && newPatchDetail != null) { ObjectHelper.CopyMatchingFields(newPatchDetail, patchDetailItem); } return blRun; } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"识别[{patchDetailItem.SrcImage}]时出错:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); return false; } finally { waitWindow.Close(); } } private ScrollViewer _scrollViewer; private ScrollViewer GetScrollViewer(DependencyObject obj) { if(_scrollViewer != null) { return _scrollViewer; } if (obj is ScrollViewer) { _scrollViewer = (ScrollViewer)obj; return obj as ScrollViewer; } for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { var child = VisualTreeHelper.GetChild(obj, i); var scrollViewer = GetScrollViewer(child); if (scrollViewer != null) { _scrollViewer = scrollViewer; return scrollViewer; } } return null; } ////-------------以下代码被作废,暂不使用此方法------------------- //private PatchPrgDialog PatchPrgDialog; // 用于弹出进度对话框 //public event Action OnProcessingProgressChanged; // 用于通知进度 //public event Action OnProcessingCompleted; // 用于通知完成 //public event Action OnProcessingStopped; // 用于通知停止 //private BackgroundWorker worker; ////private bool isProcessing; //private bool cancelRequested; //private int TotalImages; ////开始批量识别任务 //public void StartPatchTask2() //{ // worker = new BackgroundWorker(); // worker.DoWork += Worker_DoWork; // worker.RunWorkerCompleted += Worker_RunWorkerCompleted; // worker.ProgressChanged += Worker_ProgressChanged; // worker.WorkerReportsProgress = true; // worker.WorkerSupportsCancellation = true; // PatchPrgDialog = new PatchPrgDialog(this); // 传递 UserControl 实例给对话框 // PatchPrgDialog.StartProcessing(); //} //// 启动处理 //public void StartProcessing() //{ // //isProcessing = true; // cancelRequested = false; // worker.RunWorkerAsync(); //} //// 停止处理 //public void StopProcessing() //{ // cancelRequested = true; // worker.CancelAsync(); //} //// 执行后台处理任务 //private void Worker_DoWork(object sender, DoWorkEventArgs e) //{ // //int totalImages = 100; // 假设有100张图片要处理 // TotalImages = 100; // for (int i = 1; i <= TotalImages; i++) // { // if (cancelRequested) // { // e.Cancel = true; // break; // } // // 模拟处理图片 // Thread.Sleep(1000); // 这里模拟了图片处理的延迟 // // 更新进度 // //worker.ReportProgress((i * 100) / totalImages); // worker.ReportProgress(i); // } //} //// 更新进度条 //private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e) //{ // //progressBar.Value = e.ProgressPercentage; // OnProcessingProgressChanged?.Invoke(e.ProgressPercentage,TotalImages); //} //// 处理完成或被取消 //private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) //{ // if (e.Cancelled) // { // OnProcessingStopped?.Invoke(); // } // else // { // OnProcessingCompleted?.Invoke(); // } //} //----------------------------------------------------------------------------------- } // 自定义事件参数类 public class PatchDetailItemChangedEventArgs : EventArgs { public PatchDetailItem SelectedPatchDetailItem { get; } public PatchDetailItemChangedEventArgs(PatchDetailItem selectedData) { SelectedPatchDetailItem = selectedData; } } }