using MeterVision.Config; using MeterVision.db; using MeterVision.Dlg; using MeterVision.FreeAi; using MeterVision.Helper; using MeterVision.model; using MeterVision.RemoteApi; using MeterVision.Util; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Linq; using System.Net; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; //using System.Linq; //using System.Text; //using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; //using System.Windows.Data; //using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; //using System.Windows.Media; //using System.Windows.Media.Imaging; //using System.Windows.Navigation; //using System.Windows.Shapes; namespace MeterVision.Single { /// /// UCSingleGrid.xaml 的交互逻辑 /// public partial class UCSingleGrid : UserControl, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); //定义数据源 public BulkObservableCollection SingleDetailItemList { get; set; } //定义事件,用于通知外部组件选中项已更改(用于其它窗体或用户控件注册) public event EventHandler OnSelectedSingDetailItemChanged; private SingleDetailItem _selectedSingleDetailItem; public SingleDetailItem SelectedSingleDetailItem { get => _selectedSingleDetailItem; set { if(_selectedSingleDetailItem != value) { _selectedSingleDetailItem = value; OnPropertyChanged(nameof(SelectedSingleDetailItem)); OnSelectedSingDetailItemChanged?.Invoke(this, new SingleDetailItemChangedEventArgs(value)); } } } public CfginiItem mConfigItem { get; set; } public PageModel SingleDetailPage { get; set; } private int _totalRecord; public int TotalRecords { get => _totalRecord; set { if (_totalRecord != value) { _totalRecord = value; OnPropertyChanged(nameof(TotalRecords)); } } } public UCSingleGrid() { InitializeComponent(); SingleDetailItemList = new BulkObservableCollection(); dgSingle.ItemsSource = SingleDetailItemList; mConfigItem = CfginiItem.GetConfigItem(); SingleDetailPage = new PageModel { PageSize = mConfigItem.PageSize3, //mConfigItem.SinglePageSize, PageNumber = 1 }; //mConfigItem.OnSinglePageSizeChanged += MConfigItem_OnSinglePageSizeChanged; //mConfigItem.OnSinglePageSizeChanged += MConfigItem_OnSinglePageSizeChanged1; mConfigItem.OnPageSize3Changed += MConfigItem_OnPageSize1Changed; //InitializeAsync(); LoadSingleDetailItemList(); //LoadSingleDetailItemList_sync(); //CreateDemoData(); this.DataContext = this; } private void MConfigItem_OnPageSize1Changed(int pageSize3) { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { SingleDetailPage.InitDefaulValue(pageSize3); LoadSingleDetailItemList(); //LoadSingleDetailItemList_sync(); } catch { } finally { _semaphore.Release(); } } //private async void LoadSingleDetailItemList_sync() //{ // await LoadSingleDetailItemList(); //} //private async void InitializeAsync() //{ // await LoadSingleDetailItemList(); //} //private async void MConfigItem_OnSinglePageSizeChanged(object sender, PageSizeChangedEventArgs e) //{ // SingleDetailPage.InitDefaulValue(e.PageSize); // await LoadSingleDetailItemList(); //} public void RefreshData() { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { SingleDetailPage.InitDefaulValue(); //await LoadSingleDetailItemList(); LoadSingleDetailItemList(); } catch { } finally { _semaphore.Release(); } } public async void LoadSingleDetailItemList() { SingleDetailItemList.Clear(); try { var result = await Task.Run(() => { return DBSingle.GetPagedSingleDetails(SingleDetailPage.PageNumber, SingleDetailPage.PageSize); }); TotalRecords = result.Item1; SingleDetailPage.PageCount = result.Item2; List singleDetails = result.Item3; //更新数据需要在主线中进行 //await Application.Current.Dispatcher.BeginInvoke(new Action(() => //{ //int index = 0; //foreach (TSingleDetail singleDetail in singleDetails) //{ // index++; // SingleDetailItem item = new SingleDetailItem(singleDetail); // item.Index = index + ((SingleDetailPage.PageNumber - 1) * SingleDetailPage.PageSize); // SingleDetailItemList.Add(item); //}//foreach var patchDetailItems = singleDetails.Select((singleDetail, i) => new SingleDetailItem(singleDetail) { Index = (SingleDetailPage.PageNumber - 1) * SingleDetailPage.PageSize + i + 1 }).ToList(); SingleDetailItemList.AddRange(patchDetailItems); SelectedSingleDetailItem = null; //})); //return true; } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"加载数据时发生错误:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); //return false; } } public async Task LoadSingleDetailItemListAsync() { SingleDetailItemList.Clear(); try { var result = await Task.Run(() => { return DBSingle.GetPagedSingleDetails(SingleDetailPage.PageNumber, SingleDetailPage.PageSize); }); TotalRecords = result.Item1; SingleDetailPage.PageCount = result.Item2; List singleDetails = result.Item3; var patchDetailItems = singleDetails.Select((singleDetail, i) => new SingleDetailItem(singleDetail) { Index = (SingleDetailPage.PageNumber - 1) * SingleDetailPage.PageSize + i + 1 }).ToList(); SingleDetailItemList.AddRange(patchDetailItems); SelectedSingleDetailItem = null; } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"加载数据时发生错误:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); //return false; } } //private imgWindow mImgWindow; private void SrcImage_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var image = sender as Image; if (image == null) return; var dataContext = image.DataContext as SingleDetailItem; if (dataContext == null) return; //var dialog = new ImageViewerWindow(dataContext.SourceImagePath) if (!File.Exists(dataContext.SrcImage)) return; //((MainWindow)Application.Current.MainWindow).overlay.Visibility = Visibility.Visible; imgWindow dialog = new imgWindow(dataContext.SrcImage) { Owner = Application.Current.MainWindow }; //dialog.ShowDialog(); dialog.Show(); //this.PreviewMouseDown += UCSingleGrid_PreviewMouseDown; // 添加事件监听器来监听鼠标点击事件 //dialog.PreviewMouseDown += Dialog_PreviewMouseDown; //// 添加事件监听器来监听键盘按键事件 //dialog.PreviewKeyDown += Dialog_PreviewKeyDown; //// 对话框关闭后隐藏覆盖层 //((MainWindow)Application.Current.MainWindow).overlay.Visibility = Visibility.Visible; //this.dialog } private void UCSingleGrid_PreviewMouseDown(object sender, MouseButtonEventArgs e) { //var dialog = (imgWindow)sender; //if(mImgWindow != null) //{ // mImgWindow.Close(); //} //// 检查点击是否发生在对话框外部 ////if (e.OriginalSource == dialog && !dialog.Content.IsMouseOver) ////{ //// dialog.Close(); ////} } //private void Dialog_PreviewMouseDown(object sender, MouseButtonEventArgs e) //{ // var dialog = (imgWindow)sender; // // 检查点击是否发生在对话框外部 // if (e.OriginalSource == dialog && !dialog.Content.IsMouseOver) // { // dialog.Close(); // } //} //private void Dialog_PreviewKeyDown(object sender, KeyEventArgs e) //{ // var dialog = (imgWindow)sender; // // 当按下 Esc 键时关闭对话框 // if (e.Key == Key.Escape) // { // dialog.Close(); // } //} private void DstImage_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var image = sender as Image; if (image == null) return; var dataContext = image.DataContext as SingleDetailItem; 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(); } private void UserControl_DragEnter(object sender, DragEventArgs e) { // 处理网页拖拽 //if (e.Data.GetDataPresent(DataFormats.Text) || e.Data.GetDataPresent(DataFormats.Bitmap)) if (e.Data.GetDataPresent(DataFormats.Text)) { e.Effects = DragDropEffects.Copy; } else if (e.Data.GetDataPresent(DataFormats.FileDrop)) { e.Effects = DragDropEffects.Copy; // 如果是文件拖拽,允许复制 } else { e.Effects = DragDropEffects.None; // 不支持的格式 } e.Handled = true; } private void UserControl_PreviewDragOver(object sender, DragEventArgs e) { //if (e.Data.GetDataPresent(DataFormats.FileDrop)) //{ // // 获取拖拽的文件数组 // string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); // // 检查是否只拖拽了一个文件,并且该文件不是文件夹 // if (files.Length == 1 && File.Exists(files[0])) // { // e.Effects = DragDropEffects.Copy; // } // else // { // e.Effects = DragDropEffects.None; // } //} //else //{ // e.Effects = DragDropEffects.None; //} //e.Handled = true; //if (e.Data.GetDataPresent(DataFormats.Text) || e.Data.GetDataPresent(DataFormats.Bitmap)) if (e.Data.GetDataPresent(DataFormats.Text)) { e.Effects = DragDropEffects.Copy; } else if (e.Data.GetDataPresent(DataFormats.FileDrop)) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); if (files.Length == 1 && File.Exists(files[0])) { e.Effects = DragDropEffects.Copy; } else { e.Effects = DragDropEffects.None; } } else { e.Effects = DragDropEffects.None; } e.Handled = true; } private void UserControl_Drop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { // 获取拖拽的文件数组 string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); // 确保只拖拽了一个文件 if (files.Length != 1) { //MessageBox.Show("只能拖拽一个文件。", "错误", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(Application.Current.MainWindow, "只能拖拽一个文件。", "错误", MessageBoxButton.OK, MessageBoxImage.Error); return; } // 获取单个文件路径 string file = files[0]; // 验证文件是否为有效的 JPG 文件,并且文件大小不超过 100KB if ( (ThisApp.IsJpgFile(file) || ThisApp.IsBmpFile(file) ) && ThisApp.IsFileSizeValid(file) && ThisApp.IsImageDimensionsValid(file)) { // 调用图像处理方法 //ProcessDragFile(file); DragRecong(file); } else { MessageBox.Show(Application.Current.MainWindow, $"文件 {file} 不符合要求:必须是小于 300KB 的 JPG 文件,且图像尺寸必须为 320x240。", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } else if (e.Data.GetDataPresent(DataFormats.Text)) { // 处理网页拖拽的图像(URL) string imageUrl = e.Data.GetData(DataFormats.Text).ToString(); // 如果需要,你可以检查 URL 是否以图像文件类型(例如 .jpg, .png)结尾 if (Uri.IsWellFormedUriString(imageUrl, UriKind.Absolute)) { // 处理图像 URL string localFilePath = ProcessImageFromUrl(imageUrl); if (localFilePath != null) { DragRecong(localFilePath); } } }//else if } private string ProcessImageFromUrl(string imageUrl) { // 你可以通过 WebRequest 下载并显示图像,或者直接显示 URL try { string saveFilePath = null; using (var client = new WebClient()) { byte[] imageData = client.DownloadData(imageUrl); MemoryStream memoryStream = new MemoryStream(imageData); BitmapImage bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.StreamSource = memoryStream; bitmapImage.EndInit(); // 获取图像的宽度和高度 Console.WriteLine($"Width: {bitmapImage.PixelWidth}"); Console.WriteLine($"Height: {bitmapImage.PixelHeight}"); if(bitmapImage.PixelWidth != ThisApp.RequiredWidth || bitmapImage.PixelHeight != ThisApp.RequiredHeight) { MessageBox.Show(Application.Current.MainWindow, "图像尺寸不符合320*240的要求。", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); return null; } if(memoryStream.Length > ThisApp.MaxFileSize) { MessageBox.Show(Application.Current.MainWindow, "图像的文件大小不符合要求。", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); return null; } //判读文件名称是否符号要求,暂时不管 //获取保存网络图片的路径 string folerPath = Path.Combine(mConfigItem.TransImgPath, "www"); if (!Directory.Exists(folerPath)) { Directory.CreateDirectory(folerPath); } //在这里保存成本地文件,并能保留imageUrl中的文件名 // 提取文件名(从 URL 获取文件名部分) string fileName = Path.GetFileName(new Uri(imageUrl).LocalPath); saveFilePath = Path.Combine(folerPath, fileName); // 保存图像到本地文件 if (!File.Exists(saveFilePath)) { File.WriteAllBytes(saveFilePath, imageData); } // 打印保存路径 Console.WriteLine($"Image saved to: {saveFilePath}"); } return saveFilePath; } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"加载图像失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); return null; } } public async void DragRecong(string srcImagePath) { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { var singleDetailItem = new SingleDetailItem() { SingleDetailId = Guid.NewGuid().ToString(), CreateTime = ThisApp.GetNowTime_yyyyMMddHHmmss(), SrcImage = srcImagePath, DeviceSn = "", SampleTime = "" }; if (TryExtractNumbers(srcImagePath, out string deviceSn, out string sampleTime)) { singleDetailItem.DeviceSn = deviceSn; singleDetailItem.SampleTime = sampleTime; } TSingleDetail singleDetail = new TSingleDetail(); ObjectHelper.CopyMatchingFields(singleDetailItem, singleDetail); if (DBSingle.InsertTSingleDetail0(singleDetail)) { SingleDetailPage.PageNumber = 1; //LoadSingleDetailItemList(); await LoadSingleDetailItemListAsync(); if (SingleDetailItemList.Count > 0) { SelectedSingleDetailItem = SingleDetailItemList[0]; //dgSingle.ScrollIntoView(dgSingle.Items[0]); var scrollViewer = GetDgSingleScrollViewer(dgSingle); scrollViewer?.ScrollToTop(); //插入成功后进行识别20250725后新加的 RecongSingleDetail(false, SelectedSingleDetailItem); } } } catch { } finally { _semaphore.Release(); } } static bool TryExtractNumbers(string fileName, out string deviceSn, out string recvTime) { deviceSn = string.Empty; recvTime = string.Empty; string pattern = @"^(\d{11})_(\d{14})_.*$"; Match match = Regex.Match(fileName, pattern); if (match.Success) { deviceSn = match.Groups[1].Value; recvTime = match.Groups[2].Value; return true; } return false; } public void InsertFilesToDatabase(List filePaths, ProgressDialog progressDialog) { int totalFiles = filePaths.Count; int currentFile = 0; foreach (var filePath in filePaths) { // 插入文件路径到数据库 //InsertFileToDatabase(filePath); TSingleDetail singleDetail = new TSingleDetail() { SingleDetailId = Guid.NewGuid().ToString(), CreateTime = ThisApp.GetNowTime_yyyyMMddHHmmss(), SrcImage = filePath }; DBSingle.InsertTSingleDetail0(singleDetail); // 更新进度条 currentFile++; UpdateProgress(progressDialog, currentFile, totalFiles); } } public void UpdateProgress(ProgressDialog progressDialog, int currentFile, int totalFiles) { // 更新进度条的进度 double progress = (double)currentFile / totalFiles * 100; progressDialog.UpdateProgress(progress); } public void NextPage() { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { if (SingleDetailPage.PageNumber < SingleDetailPage.PageCount) { SingleDetailPage.PageNumber += 1; LoadSingleDetailItemList(); } } catch { } finally { _semaphore.Release(); } } public void PrePage() { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { if (SingleDetailPage.PageNumber > 1) { SingleDetailPage.PageNumber -= 1; LoadSingleDetailItemList(); } } catch { } finally { _semaphore.Release(); } } public void FirstPage() { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { if (SingleDetailPage.PageNumber > 1) { SingleDetailPage.PageNumber = 1; LoadSingleDetailItemList(); } } catch { } finally { _semaphore.Release(); } } public void LastPage() { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { if (SingleDetailPage.PageNumber < SingleDetailPage.PageCount) { SingleDetailPage.PageNumber = SingleDetailPage.PageCount; LoadSingleDetailItemList(); } } catch { } finally { _semaphore.Release(); } } public void SpeciPage(int pageNumber) { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { if (pageNumber != SingleDetailPage.PageNumber && pageNumber > 0 && pageNumber <= SingleDetailPage.PageCount) { SingleDetailPage.PageNumber = pageNumber; LoadSingleDetailItemList(); } } catch { } finally { _semaphore.Release(); } } // 辅助方法:查找指定类型的祖先元素 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 BtnDelDetailItem_Click(object sender, RoutedEventArgs e) { //删除选中项 Button button = sender as Button; if (button == null) return; DataGridRow row = FindAncestor(button); if (row == null) return; //获取当前行绑定的数据项 SingleDetailItem selectedItem = row.Item as SingleDetailItem; DeleteSelectedItem(selectedItem); } private void BtnRecongDetailItem_Click(object sender, RoutedEventArgs e) { Button button = sender as Button; if (button == null) return; DataGridRow row = FindAncestor(button); if (row == null) return; //获取当前行绑定的数据项 SingleDetailItem selectedItem = row.Item as SingleDetailItem; RecongSingleDetail(false, SelectedSingleDetailItem); } 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; //获取当前行绑定的数据项 SingleDetailItem selectedItem = row.Item as SingleDetailItem; ShowLogViewer(selectedItem); } private void ShowLogViewer(SingleDetailItem 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 async void DeleteSelectedItem(SingleDetailItem 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 = DBSingle.DeleteTSingleDetailById(selectedItem.SingleDetailId); }); if (deleteSuccess) { //await Application.Current.Dispatcher.BeginInvoke(new Action(() => //{ // 从数据源中移除该条目 SingleDetailItemList.Remove(selectedItem); SelectedSingleDetailItem = null; //})); } } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"删除失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } finally { waitWindow.Close(); } } //清空所有的列表数据 public async void ClearAllSingleDetail() { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { //清空提示 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 blClearAll = false; await Task.Run(() => { blClearAll = DBSingle.ClearTSingleDetailTable(); }); if (blClearAll) { SingleDetailPage.InitDefaulValue(); LoadSingleDetailItemList(); } } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"清空失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } finally { waitWindow.Close(); } } catch { } finally { _semaphore.Release(); } } private void MiDelete_Click(object sender, RoutedEventArgs e) { if (SelectedSingleDetailItem == null) return; //获取当前行绑定的数据项 DeleteSelectedItem(SelectedSingleDetailItem); } private void MiRecong_Click(object sender, RoutedEventArgs e) { if (SelectedSingleDetailItem == null) return; RecongSingleDetail(false, SelectedSingleDetailItem); } private async void RecongSingleDetail(bool isAdd, SingleDetailItem singleDetailIte) { string jpgFile = singleDetailIte.SrcImage; if (!File.Exists(jpgFile)) { MessageBox.Show(Application.Current.MainWindow, $"文件:{jpgFile}不存在!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); return; } //bool blRun = await RunAI(isAdd, singleDetailIte); bool blRun = await Run_HttpApi_Recogn(isAdd, singleDetailIte); if (blRun) { //MessageBox.Show(Application.Current.MainWindow, "识别成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); } else { MessageBox.Show(Application.Current.MainWindow, "识别失败!", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } //允许http的远程识别 private async Task Run_HttpApi_Recogn(bool isAdd,SingleDetailItem singleDetailItem) { string titleInfo = "正在识别,请稍后..."; WaitWindow waitWindow = new WaitWindow(titleInfo) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; waitWindow.Show(); try { TSingleDetail newSingleDetail = null; //调用不会出现错误,函数中已增加try catch CallApiResult apiResult = await RecogApi.CallRecogn(singleDetailItem.SrcImage, new MetaData()); if(apiResult.callResult == 0) { Console.WriteLine(apiResult.errorMessage); MessageBox.Show(Application.Current.MainWindow, $"识别[{singleDetailItem.SrcImage}]时出错:{apiResult.errorMessage}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); return false; } newSingleDetail = new TSingleDetail(singleDetailItem, apiResult); //更新数据 bool blOpration; //实际传输的isAdd总是false if (isAdd) { blOpration = DBSingle.InsertSingleDetail(newSingleDetail); } else { blOpration = DBSingle.UpdateSingleDetailByResult(newSingleDetail); } //return blOpration; //在主线程中更新DataGrid的Row数据 if (blOpration && !isAdd && newSingleDetail != null) { //singleDetailItem = newSingleDetail; ObjectHelper.CopyMatchingFields(newSingleDetail, singleDetailItem); //singleDetailItem.MeterType = 2; } return blOpration; } catch(Exception ex) { Dispatcher.Invoke(()=> { MessageBox.Show(Application.Current.MainWindow, $"识别[{singleDetailItem.SrcImage}]时出错:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); }); return false; } finally { waitWindow.Close(); } } private async Task RunAI(bool isAdd,SingleDetailItem singleDetailItem) { 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 { TSingleDetail newSingleDetail = null; bool blRun = await Task.Run(() => { try { ResultModel resultModel = null; try { resultModel = faRun.StartRecognition(singleDetailItem); } catch (Exception ex) { Console.WriteLine(ex.Message); } if (resultModel == null) return false; newSingleDetail = new TSingleDetail(singleDetailItem, resultModel); //更新数据 bool blOpration; //实际传输的isAdd总是false if (isAdd) { blOpration = DBSingle.InsertSingleDetail(newSingleDetail); } else { blOpration = DBSingle.UpdateSingleDetailByResult(newSingleDetail); } return blOpration; } catch(Exception ex) { Dispatcher.Invoke(() => { MessageBox.Show(Application.Current.MainWindow, $"{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); }); return false; } }); //------ //在主线程中更新DataGrid的Row数据 if (blRun && !isAdd && newSingleDetail != null) { //singleDetailItem = newSingleDetail; ObjectHelper.CopyMatchingFields(newSingleDetail, singleDetailItem); //singleDetailItem.MeterType = 2; } return blRun; } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"识别[{singleDetailItem.SrcImage}]时出错:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); return false; } finally { waitWindow.Close(); } } private void FaRun_OnAiRealLogInfo(object sender, AiRealLogEventArgs e) { Console.Write(e.mLogInfo); } private void MiViewLog_Click(object sender, RoutedEventArgs e) { if(SelectedSingleDetailItem != null) { ShowLogViewer(SelectedSingleDetailItem); } } private void MiAddMemo_Click(object sender, RoutedEventArgs e) { if (SelectedSingleDetailItem == null) return; AddMemo(SelectedSingleDetailItem); } private void AddMemo(SingleDetailItem 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 (DBSingle.UpdateSingleDetailMemo(detailItem.SingleDetailId, memo)) { detailItem.Memo = memo; } } } private void Memo_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if(e.ClickCount == 2) { if (SelectedSingleDetailItem == null) return; AddMemo(SelectedSingleDetailItem); } } private void BtnConfig_Click(object sender, RoutedEventArgs e) { Button button = sender as Button; if (button == null) return; DataGridRow row = FindAncestor(button); if (row == null) return; SingleDetailItem detailItem = row.Item as SingleDetailItem; EditSingleConfig dialog = new EditSingleConfig(detailItem) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; if (dialog.ShowDialog() == true) { detailItem = dialog.mDetailItem; } } private ScrollViewer _dgSingleScrollViewer; private ScrollViewer GetDgSingleScrollViewer(DependencyObject obj) { if (_dgSingleScrollViewer != null) { return _dgSingleScrollViewer; } if (obj is ScrollViewer) { _dgSingleScrollViewer = (ScrollViewer)obj; return obj as ScrollViewer; } for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { var child = VisualTreeHelper.GetChild(obj, i); var scrollViewer = GetDgSingleScrollViewer(child); if (scrollViewer != null) { _dgSingleScrollViewer = scrollViewer; return scrollViewer; } } return null; } /////////////////////////////////////////////////////////////////////////// } //自定义事件参数类 public class SingleDetailItemChangedEventArgs : EventArgs { public SingleDetailItem SelectedSingleDetailItem { get; } public SingleDetailItemChangedEventArgs(SingleDetailItem selectedData) { SelectedSingleDetailItem = selectedData; } } }