using MeterVision.Config; using MeterVision.db; using MeterVision.Dlg; using MeterVision.model; using MeterVision.Util; using Ookii.Dialogs.Wpf; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; 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 { /// /// UCPatchMain.xaml 的交互逻辑 /// public partial class UCPatchMain : UserControl, INotifyPropertyChanged { private const int COLUMN_LEFT_WIDTH = 220; private const int COLUMN_RIGHT_WIDTH = 400; private bool LeftVisiable = true; //表示左侧的显示状态 private bool RightVisiable = true; //表示右侧的显示状态 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public ObservableCollection> PatchFindTypeKVs { get; set; } private PatchFindType _selectedPatchFindType; public PatchFindType SelectedPatchFindType { get => _selectedPatchFindType; set { if(_selectedPatchFindType != value) { _selectedPatchFindType = value; OnPropertyChanged(nameof(SelectedPatchFindType)); ucPatchGird.ChangePatchItemOrFinType(SelectedPatchItem, SelectedPatchFindType); } } } public PageModel PatchPage { get; set; } //定义识别任务数据源 public ObservableCollection PatchItemList { get; set; } public CfginiItem mConfigItem { get; set; } private PatchItem _selectedPatchItem; public PatchItem SelectedPatchItem { get => _selectedPatchItem; set { _selectedPatchItem = value; OnPropertyChanged(nameof(SelectedPatchItem)); //ucPatchGird.CurPatchItem = value; ucPatchGird.ChangePatchItemOrFinType(SelectedPatchItem, SelectedPatchFindType); Apply_UCPatchDetail_Title(value); } } //总共的Patch数量 private int _totalPatchRecords; public int TotalPatchRecords { get => _totalPatchRecords; set { if(_totalPatchRecords != value) { _totalPatchRecords = value; OnPropertyChanged(nameof(TotalPatchRecords)); } } } private void Apply_UCPatchDetail_Title(PatchItem patchItem) { if (patchItem == null) { //pnlDetailsTitle.Visibility = Visibility.Hidden; pnlDetailFunc.Visibility = Visibility.Hidden; txtPatchName.Text = "请选择左侧任务"; } else { //pnlDetailsTitle.Visibility = Visibility.Visible; pnlDetailFunc.Visibility = Visibility.Visible; txtPatchName.Text = $"{patchItem.Index}.{patchItem.PatchName}[{patchItem.DetailCount}]"; //patchItem.PatchName; } } private void InitRightControls(PatchDetailItem PatchDetailItem) { pnlImage.Visibility = txtRightItemIndex.Visibility = pnlLog.Visibility = PatchDetailItem == null ? Visibility.Collapsed : Visibility.Visible; } private void InitPatchFindTypeKVs() { PatchFindTypeKVs = new ObservableCollection>() { new KeyValuePair(PatchFindType.ALL, "所有"), new KeyValuePair(PatchFindType.RUN_YES, "已识别"), new KeyValuePair(PatchFindType.RUN_NO, "未识别"), new KeyValuePair(PatchFindType.RESULT_OK, "识别正确"), new KeyValuePair(PatchFindType.RESULT_ERROR, "识别错误"), new KeyValuePair(PatchFindType.ALL_NO_STAND_VALUE, "无标准值"), new KeyValuePair(PatchFindType.RUN_YES_NO_STAND_VALUE, "已识别+无标准值"), new KeyValuePair(PatchFindType.RUN_NO_NO_STAND_VALUE, "未识别+无标准值"), new KeyValuePair(PatchFindType.HAVE_MEMO, "有备注"), }; // ALL_NO_STAND_VALUE = 6, //所有无标准值项 //RUN_YES_NO_STAND_VALUE = 7, //已运行的无标准值的项 //RUN_NO_NO_STAND_VALUE = 8 //未运行的无标准值的项 } public UCPatchMain() { InitializeComponent(); PatchItemList = new ObservableCollection(); dgPatch.ItemsSource = PatchItemList; Apply_UCPatchDetail_Title(null); InitRightControls(null); //订阅UCPatchGrid的选中项变化事件 ucPatchGird.OnSelectedPatchDetailItemChanged += UcPatchGird_OnSelectedPatchDetailItemChanged; ucPatchGird.OnRefreshPatchItem += UcPatchGird_OnRefreshPatchItem; mConfigItem = CfginiItem.GetConfigItem(); PatchPage = new PageModel { //PageSize = mConfigItem.CatalogPageSize, PageSize = mConfigItem.PatchCatalogPageSize, PageNumber = 1 }; mConfigItem.OnPatchCatalogPageSizeChnaged += MConfigItem_OnPatchCatalogPageSizeChnaged; this.DataContext = this; LoadPatchItemListAsync(); InitPatchFindTypeKVs(); SelectedPatchFindType = PatchFindType.ALL; //控制左右2侧栏目的显示 LeftVisiable = true; ChangeLeftVisiable(LeftVisiable); RightVisiable = true; ChangeRightVisiable(RightVisiable); } private async void MConfigItem_OnPatchCatalogPageSizeChnaged(int pageSize) { PatchPage.InitDefaulValue(pageSize); bool blLoad = await LoadPatchItemList(); if (blLoad) { SelectedPatchItem = null; } } private async void LoadPatchItemListAsync() { await LoadPatchItemList(); } private void UcPatchGird_OnRefreshPatchItem(string patchId) { if ( string.IsNullOrEmpty(patchId) ) return; //VPatch vPatch = null; //await Task.Run(() => //{ // vPatch = DBPatch.GetVPatchById(patchId); //}); //if(vPatch != null) //{ // //var NewPatchItem = new PatchItem(vPatch); // foreach(var patchItem in PatchItemList) // { // if(patchItem.PatchId == vPatch.PatchId) // { // ObjectHelper.CopyMatchingFields(vPatch, patchItem); // break; // } // }//foreach //}//if vpatch!=null RefresUIPatchItem(patchId); } //处理UCPatchGrid的选中项变化事件 private void UcPatchGird_OnSelectedPatchDetailItemChanged(object sender, PatchDetailItemChangedEventArgs e) { InitRightControls(e.SelectedPatchDetailItem); txtRightItemIndex.Text = string.Empty; // 如果有选中的数据项,则将图片路径传递给 UCImage if (e.SelectedPatchDetailItem != null) { ucImagerSource.ImageSource = e.SelectedPatchDetailItem.SrcImage; ucImageResult.ImageSource = e.SelectedPatchDetailItem.DstImage; ucImagerSource.ImageName = "原始图片"; ucImageResult.ImageName = "结果图片"; //设置log显示 SetLogContent(e.SelectedPatchDetailItem); if (SelectedPatchItem != null) { txtRightItemIndex.Text = $"{SelectedPatchItem.Index}. - {e.SelectedPatchDetailItem.Index}."; } } } private async void SetLogContent(PatchDetailItem detailItem) { if(detailItem != null && File.Exists(detailItem.LogPath)) { LogRichTextBox.Document.Blocks.Clear(); await Task.Run(() => { //Task.Delay(2000); //Thread.Sleep(4000); string content = File.ReadAllText(detailItem.LogPath); content = $"{detailItem.Index}. {detailItem.LogPath}\n\n{content}"; Application.Current.Dispatcher.Invoke(() => { LogRichTextBox.ScrollToHome(); Paragraph logParagraph = new Paragraph(new Run(content)); LogRichTextBox.Document.Blocks.Add(logParagraph); }); }); } } private async Task LoadPatchItemList() { PatchItemList.Clear(); try { var result = await Task.Run(() => { return DBPatch.GetPagedVPatchs(PatchPage.PageNumber, PatchPage.PageSize); }); TotalPatchRecords = result.Item1; PatchPage.PageCount = result.Item2; List patchs = result.Item3; int index = 0; foreach (VPatch vPatch in patchs) { index++; PatchItem patchItem = new PatchItem(vPatch); patchItem.Index = index + (PatchPage.PageNumber - 1) * PatchPage.PageSize; PatchItemList.Add(patchItem); } return true; } catch(Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"加载数据时发生错误:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); return false; } } private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) { // 只允许数字输入 e.Handled = !Regex.IsMatch(e.Text, @"^\d$"); } private async void BtnPatchPrePage_Click(object sender, RoutedEventArgs e) { if (PatchPage.PageNumber > 1) { PatchPage.PageNumber -= 1; bool blLoad = await LoadPatchItemList(); if (blLoad && PatchItemList.Count > 0) { dgPatch.ScrollIntoView(PatchItemList[0]); } } } private async void BtnPatchNextPage_Click(object sender, RoutedEventArgs e) { if (PatchPage.PageNumber < PatchPage.PageCount) { PatchPage.PageNumber += 1; bool blLoad = await LoadPatchItemList(); if (blLoad && PatchItemList.Count > 0) { dgPatch.ScrollIntoView(PatchItemList[0]); } } } private void BtnPatchDetailFirstPage_Click(object sender, RoutedEventArgs e) { ucPatchGird.FirstPage(); } private void BtnPatchDetailPrePage_Click(object sender, RoutedEventArgs e) { ucPatchGird.PrePage(); } private void BtnPatchDetailNextPage_Click(object sender, RoutedEventArgs e) { ucPatchGird.NextPage(); } private void BtnPatchDetailLastPage_Click(object sender, RoutedEventArgs e) { ucPatchGird.LastPage(); } private void BtnPatchDetailSpeciPage_Click(object sender, RoutedEventArgs e) { try { int pageNumber = int.Parse(txtPatchDetailPageNumber.Text.ToString()); ucPatchGird.SpeciPage(pageNumber); } catch { } } private async void BtnAddPatch_Click(object sender, RoutedEventArgs e) { AddPatchDlg dialog = new AddPatchDlg() { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; if(dialog.ShowDialog() == true) { TPatch patch = dialog.NewPatch; //获取VPatch PatchPage.InitDefaulValue(mConfigItem.PatchPageSize); bool blLoad = await LoadPatchItemList(); if (blLoad && PatchItemList.Count > 0) { SelectedPatchItem = PatchItemList[0]; dgPatch.ScrollIntoView(SelectedPatchItem); } } } private async void BtnDelPatch_Click(object sender, RoutedEventArgs e) { bool blDelte = await DeletePatchItem(); } private async Task DeletePatchItem() { bool blDelete = false; if (SelectedPatchItem == null) return blDelete; // 弹出确认对话框 MessageBoxResult result = MessageBox.Show( $"您确定要删除[{SelectedPatchItem.PatchName}]任务吗?\n此操作无法撤销。", "确认删除", MessageBoxButton.YesNo, // 提供“是”和“否”按钮 MessageBoxImage.Warning // 使用警告图标 ); if (result != MessageBoxResult.Yes) { return blDelete; } //开始删除操作 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.DeletePatchAndDetails(SelectedPatchItem.PatchId); //Task.Delay(200).Wait(); // 模拟延迟 }); if (deleteSuccess) { //await LoadPatchItemList(); // 在 UI 线程上更新 ObservableCollection Application.Current.Dispatcher.Invoke(() => { PatchItemList.Remove(SelectedPatchItem); SelectedPatchItem = null; TotalPatchRecords -= 1; }); blDelete = true; } } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"删除失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } finally { //关闭等待窗口 waitWindow.Close(); } return blDelete; } private async void BtnRefresh_Click(object sender, RoutedEventArgs e) { PatchPage.InitDefaulValue(); bool blLoad = await LoadPatchItemList(); if(blLoad && PatchItemList.Count > 0) { dgPatch.ScrollIntoView(PatchItemList[0]); } } //批量识别 private async void BtnStartTask_Click(object sender, RoutedEventArgs e) { bool blTask = await ucPatchGird.StartPatchTask(); //更新目录内容 if (blTask && SelectedPatchItem != null) { VPatch vPatch = null; await Task.Run(() => { vPatch = DBPatch.GetVPatchById(SelectedPatchItem.PatchId); }); if (vPatch != null) { //var NewPatchItem = new PatchItem(vPatch); foreach (var patchItem in PatchItemList) { if (patchItem.PatchId == vPatch.PatchId) { ObjectHelper.CopyMatchingFields(vPatch, patchItem); break; } }//foreach }//if vpatch!=null RefresUIPatchItem(SelectedPatchItem.PatchId); }//blTask } public async void RefresUIPatchItem(string patchId) { VPatch vPatch = null; await Task.Run(() => { vPatch = DBPatch.GetVPatchById(patchId); }); if (vPatch != null) { foreach (var patchItem in PatchItemList) { if (patchItem.PatchId == vPatch.PatchId) { ObjectHelper.CopyMatchingFields(vPatch, patchItem); break; } }//foreach }//if vpatch!=null } private void LogScrollTop_Click(object sender, RoutedEventArgs e) { LogRichTextBox.ScrollToHome(); } private void LogScrollMiddle_Click(object sender, RoutedEventArgs e) { // 获取 LogRichTextBox 文档的总高度 //double documentHeight = LogRichTextBox.Document.ContentEnd.GetPositionAtOffset(0).GetValue("VerticalOffset"); //// 获取当前可视区域的高度 //double viewportHeight = LogRichTextBox.ViewportHeight; //// 计算中间位置 //double middleOffset = (documentHeight - viewportHeight) / 2; //// 滚动到中间位置 //LogRichTextBox.ScrollToVerticalOffset(middleOffset); } private void LogScrollBottom_Click(object sender, RoutedEventArgs e) { LogRichTextBox.ScrollToEnd(); } private void MiUpdatePatchname_Click(object sender, RoutedEventArgs e) { if (SelectedPatchItem == null) return; EditNameDlg editNameDlg = new EditNameDlg("任务", SelectedPatchItem.StandName) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; if (editNameDlg.ShowDialog() == true) { UpdateStandName(SelectedPatchItem, editNameDlg.EditName); } } private async void UpdateStandName(PatchItem patchItem, string newPatchName) { try { bool blUpdate = false; await Task.Run(() => { blUpdate = DBPatch.UpdatePatchName(patchItem.PatchId, newPatchName); }); if (blUpdate) { patchItem.StandName = newPatchName; } else { MessageBox.Show(Application.Current.MainWindow, $"修改任务名称失败。", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); } } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"修改模板名称:{ex.Message}错误", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } private async void MiDeletePatch_Click(object sender, RoutedEventArgs e) { bool blDelte = await DeletePatchItem(); } private void BtnRefreshDetail_Click(object sender, RoutedEventArgs e) { //ucPatchGird.CurPatchItem = null; //ucPatchGird.CurPatchItem = SelectedPatchItem; ucPatchGird.ChangePatchItemOrFinType(null, SelectedPatchFindType); ucPatchGird.ChangePatchItemOrFinType(SelectedPatchItem, SelectedPatchFindType); } private void AiLogSave_Click(object sender, RoutedEventArgs e) { ////ucPatchGird.SelectedPatchDetailItem; //TextRange textRange = new TextRange(LogRichTextBox.Document.ContentStart, LogRichTextBox.Document.ContentEnd); ////return textRange.Text; // 提取纯文本 //string aiLog = textRange.Text; if (ucPatchGird.SelectedPatchDetailItem == null) return; PatchDetailItem patchDetailItem = ucPatchGird.SelectedPatchDetailItem; string logPath = patchDetailItem.LogPath; ThisApp.ExportAiLog(logPath); } //控制左侧的显示和折叠 private void BtnLeftCtl_Click(object sender, RoutedEventArgs e) { bool visiable = !LeftVisiable; ChangeLeftVisiable(visiable); } private void BtnRightCtl_Click(object sender, RoutedEventArgs e) { bool visiable = !RightVisiable; ChangeRightVisiable(visiable); } private void ChangeLeftVisiable(bool visiable) { LeftVisiable = visiable; colLeft.Width = new GridLength(visiable ? COLUMN_LEFT_WIDTH : 0); btnLeftCtl.Content = visiable ? "◀️" : "▶️"; btnLeftCtl.ToolTip = visiable ? "点击隐藏左侧栏" : "点击显示左侧栏"; } private void ChangeRightVisiable(bool visiable) { RightVisiable = visiable; colRight.Width = new GridLength(visiable ? COLUMN_RIGHT_WIDTH : 0); btnRightCtl.Content = visiable ? "▶️" : "◀️" ; btnRightCtl.ToolTip = visiable ? "点击隐藏右侧栏" : "点击显示右侧栏"; } //---------------------------------------------------------------- } public enum PatchFindType { ALL = 1, //所有数据 RUN_YES = 2, //已运行识别的 RUN_NO = 3, //未运行的 RESULT_OK = 4, //结果正确的 RESULT_ERROR = 5, //结果错误的 ALL_NO_STAND_VALUE =6, //所有无标准值项 RUN_YES_NO_STAND_VALUE = 7, //已运行的无标准值的项 RUN_NO_NO_STAND_VALUE = 8, //未运行的无标准值的项 HAVE_MEMO = 9 //有备注 } //---------------------------------------------------------------------- }