using MeterVision.Config; using MeterVision.db; using MeterVision.Dlg; using MeterVision.Helper; using MeterVision.model; using MeterVision.Patch; 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; namespace MeterVision.Stand { /// /// UCStandGrid.xaml 的交互逻辑 /// public partial class UCStandGrid : UserControl, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } //public event EventHandler OnStandItemCountChanged; //StandItem standItem //public event Action OnStandItemCountChanged; private SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); private SemaphoreSlim _loadLock = new SemaphoreSlim(1, 1); //定义数据源 public BulkObservableCollection StandDetailList { get; set; } //定义事件,用于通知外部组件选中项已更改 public event EventHandler OnSelectedStandDetailItemChanged; public event Action OnDeleteStandDetailItem; public event Action OnStandDetailMark; private StandDetailItem _selectedStandDetailsItem; //定义SelectedDataItem属性,并在值变化时触发事件 public StandDetailItem SelectedStandDetailItem { get => _selectedStandDetailsItem; set { if(_selectedStandDetailsItem != value) { _selectedStandDetailsItem = value; OnPropertyChanged(nameof(SelectedStandDetailItem)); OnSelectedStandDetailItemChanged?.Invoke(this, new StandDetailItemChangedEventArgs(value)); } } } //private StandItem _curStandItem; //public StandItem CurStandItem //{ // get => _curStandItem; // set // { // if (_curStandItem != value) // { // _curStandItem = value; // //StandDetailPage.InitDefaulValue(mConfigItem.StandPageSize); // //LoadStandDetailItemList(value); // } // } //} private StationItem _curStationItem; public StationItem CurStationItem { get => _curStationItem; set { /*if(_curStationId != value) { _curStationId = value; }*/ if(_curStationItem != value) { //if (!_semaphore.Wait(0)) return; // 防止重复调用 //try //{ _curStationItem = value; StandDetailPage.InitDefaulValue(mConfigItem.StandPageSize); LoadStandDetailItemList(); //} //catch { } //finally //{ // _semaphore.Release(); //} } } } //public void ChangeStation(StandItem standItem,string stationId) //{ // bool blChangeStationId = false; // bool blChangeStandItem = false; // if(_curStationId != stationId) // { // _curStationId = stationId; // blChangeStationId = true; // } // if(_curStandItem != standItem) // { // _curStandItem = standItem; // blChangeStandItem = true; // } // if(blChangeStationId || blChangeStandItem) // { // StandDetailPage.InitDefaulValue(mConfigItem.StandPageSize); // LoadStandDetailItemList(CurStandItem); // } //} //详情分页信息 public PageModel StandDetailPage { get; set; } private int _totalRecord; public int TotalRecords { get => _totalRecord; set { if(_totalRecord != value) { _totalRecord = value; OnPropertyChanged(nameof(TotalRecords)); } } } public CfginiItem mConfigItem { get; set; } //异步方法 private async void LoadStandDetailItemList() { if (!await _loadLock.WaitAsync(0)) return; // 如果已有任务在执行,则直接返回 try { StandDetailList.Clear(); if (CurStationItem != null) { try { var result = await Task.Run(() => { return DBStand.GetPagedStandDetails( StandDetailPage.PageNumber, StandDetailPage.PageSize, CurStationItem); }); TotalRecords = result.Item1; StandDetailPage.PageCount = result.Item2; List standDetails = result.Item3; //int index = 0; //foreach (TStandDetail standDetail in standDetails) //{ // StandDetailList.Add(new StandDetailItem(standDetail)); // index++; // //更新索引号 // StandDetailList[StandDetailList.Count - 1].Index = // index + ((StandDetailPage.PageNumber - 1) * StandDetailPage.PageSize); //} var standDetailList = standDetails.Select((standDetail, i) => new StandDetailItem(standDetail) { Index = (StandDetailPage.PageNumber - 1) * StandDetailPage.PageSize + i + 1 }).ToList(); StandDetailList.AddRange(standDetailList); if (StandDetailList.Count > 0) { //await Task.Delay(100); //await Dispatcher.InvokeAsync(() => //{ //dgStandDetails.ScrollIntoView(dgStandDetails.Items[0]); //}); var scrollViewer = GetScrollViewer(dgStandDetails); scrollViewer?.ScrollToTop(); } } catch (Exception ex) { MessageBox.Show(Application.Current.MainWindow, $"加载数据时发生错误:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } if (StandDetailList.Count > 0) { SelectedStandDetailItem = StandDetailList[0]; } else { SelectedStandDetailItem = null; } } catch { } finally { _loadLock.Release(); } } public UCStandGrid() { InitializeComponent(); StandDetailList = new BulkObservableCollection(); dgStandDetails.ItemsSource = StandDetailList; //CurStandItem = null; CurStationItem = null; mConfigItem = CfginiItem.GetConfigItem(); StandDetailPage = new PageModel() { PageSize = mConfigItem.PageSize3, //mConfigItem.StandPageSize, PageNumber = 1, }; //mConfigItem.OnStandPageSizeChanged += MConfigItem_OnStandPageSizeChanged1; mConfigItem.OnPageSize3Changed += MConfigItem_OnPageSize3Changed; UCPatchGrid.OnDeleteStandDetail += UCPatchGrid_OnDeleteStandDetail; UCPatchGrid.OnUpdateStandValue += UCPatchGrid_OnUpdateStandValue; this.DataContext = this; } private void MConfigItem_OnPageSize3Changed(int pageSize3) { //throw new NotImplementedException(); if (!_semaphore.Wait(0)) return; // 防止重复调用 try { StandDetailPage.InitDefaulValue(pageSize3); LoadStandDetailItemList(); } catch { } finally { _semaphore.Release(); } } //private void MConfigItem_OnStandPageSizeChanged1(int pageSize) //{ // StandDetailPage.InitDefaulValue(pageSize); // LoadStandDetailItemList(); //} private void UCPatchGrid_OnUpdateStandValue(string arg1, string arg2) { //throw new NotImplementedException(); StandDetailItem standDetailItem = StandDetailList.FirstOrDefault(a => a.StandDetailId == arg1); if(standDetailItem != null) { standDetailItem.StandValue = arg2; } } private void UCPatchGrid_OnDeleteStandDetail(string standDetailId) { //Application.Current.Dispatcher.Invoke(() => //{ // // 从数据源中移除该条目 // StandDetailList.Remove(selectedItem); // SelectedStandDetailItem = null; // OnDeleteStandDetailItem?.Invoke(selectedItem.StandId); //}); StandDetailItem standDetailItem = StandDetailList.FirstOrDefault(a => a.StandDetailId == standDetailId); if (standDetailItem != null) { StandDetailList.Remove(standDetailItem); OnDeleteStandDetailItem?.Invoke(standDetailItem.StandId); } } private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var image = sender as System.Windows.Controls.Image; if (image == null) return; var dataContext = image.DataContext as StandDetailItem; if (dataContext == null) return; //var dialog = new ImageViewerWindow(dataContext.SourceImagePath) var dialog = new imgWindow(dataContext.SrcImage) { Owner = Application.Current.MainWindow }; dialog.Show(); } private void StandValue_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (e.ClickCount == 2) { // 获取当前行的数据上下文 var textBlock = sender as TextBlock; if (textBlock == null) return; var dataContext = textBlock.DataContext as StandDetailItem; // 替换为你的数据类型 if (dataContext == null) return; SelectedStandDetailItem = dataContext; UpdateStandvalue(dataContext); }//e.clickCount } private void UpdateStandvalue(StandDetailItem detailItem) { StandValueModel standValueModel = new StandValueModel(detailItem); var dialog = new EditStandValueDlg(standValueModel) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; //if (dialog.ShowDialog() == true) //{ // UpdateStandValue(detailItem, standValueModel); //}//if showDialog dialog.OnEditStandValue += (value) => { UpdateStandValue(detailItem, standValueModel); }; dialog.Show(); } private void UpdateStandValue(StandDetailItem detailItem,StandValueModel standValueModel) { try { //修改数据库 bool updateStandValue2 = DBStand.UpdateStandDetailStandValue(detailItem.SrcImage, standValueModel.StandValue); if (updateStandValue2) { detailItem.StandValue = standValueModel.StandValue; //MessageBox.Show(Application.Current.MainWindow, "修改标准值完成。", "提示", MessageBoxButton.OK, // MessageBoxImage.Information); } 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 UserControl_DragEnter(object sender, DragEventArgs e) { //e.Handled = true; //// Check if the dragged item is a folder //if (e.Data.GetDataPresent(DataFormats.FileDrop) && CurStandItem != null) //{ // var paths = (string[])e.Data.GetData(DataFormats.FileDrop); // if (paths != null && paths.Length > 0 && Directory.Exists(paths[0])) // { // e.Effects = DragDropEffects.Copy; // } // else // { // e.Effects = DragDropEffects.None; // } //} //else //{ // e.Effects = DragDropEffects.None; //} } //private async void UserControl_Drop(object sender, DragEventArgs e) //{ //if (e.Data.GetDataPresent(DataFormats.FileDrop) && CurStandItem != null) //{ // var paths = (string[])e.Data.GetData(DataFormats.FileDrop); // if (paths != null && paths.Length > 0) // { // var folderPath = paths[0]; // if (Directory.Exists(folderPath)) // { // await ImportStandImageFloder(folderPath); // } // } //}//if //} //public async Task ImportStandImageFloder(string folderPath) //{ // try // { // bool blLoad = await LoadJpgFilesFromFolder(folderPath); // if (blLoad) // { // StandDetailPage.InitDefaulValue(); // LoadStandDetailItemList(CurStandItem); // } // return true; // } // catch(Exception ex) // { // MessageBox.Show(Application.Current.MainWindow, // $"导入模板图像错误:{ex.Message}", "错误", // MessageBoxButton.OK, MessageBoxImage.Error); // return false; // } //} //private async Task LoadJpgFilesFromFolder(string folderPath) //{ // //var jpgFiles = Directory.GetFiles(folderPath, "*.jpg", SearchOption.AllDirectories); // var jpgFiles = Directory.GetFiles(folderPath, "*.jpg", SearchOption.AllDirectories) // .Concat(Directory.GetFiles(folderPath, "*.bmp", SearchOption.AllDirectories)) // .ToArray(); // List fileList = new List(); // foreach (var filePath in jpgFiles) // { // /*_fileItems.Add(new FileItem // { // FileName = Path.GetFileName(filePath), // FilePath = filePath, // FileSize = new FileInfo(filePath).Length // });*/ // if( (ThisApp.IsJpgFile(filePath) || ThisApp.IsBmpFile(filePath) ) && // ThisApp.IsFileSizeValid(filePath) && // ThisApp.IsImageDimensionsValid(filePath)) // { // fileList.Add(filePath); // } // }//foreach // if(fileList.Count == 0) // { // MessageBox.Show(Application.Current.MainWindow, // "没有找到符号要求的图片文件。", "提示", MessageBoxButton.OK, MessageBoxImage.Information); // return false; // } // //加载数据到数据库中 // return await InsertFilesWithProgress(fileList); //} //public async Task InsertFilesWithProgress(List filePaths) //{ // // 弹出一个非模式对话框来显示进度 // ProgressDialog progressDialog = new ProgressDialog() // { // Owner = Application.Current.MainWindow, // WindowStartupLocation = WindowStartupLocation.CenterOwner // }; // progressDialog.Show(); // try // { // // 任务来异步执行文件插入 // bool blInsert = await InsertFilesToDatabase(filePaths, progressDialog); // //Task.Run(() => InsertFilesToDatabase(filePaths, progressDialog)); // //刷新CurItem // if (blInsert) // { // OnStandItemCountChanged?.Invoke(this, new StandItemCountChangedEventArgs(CurStandItem)); // } // return blInsert; // } // catch (Exception ex) // { // MessageBox.Show(Application.Current.MainWindow, $"操作数据库失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); // return false; // } // finally // { // // 关闭进度对话框 // progressDialog.Close(); // } //} //public async Task InsertFilesToDatabase(List filePaths, ProgressDialog progressDialog) //{ // int totalFiles = filePaths.Count; // int currentFile = 0; // int insertCount = 0; // try // { // await Task.Run(() => // { // foreach (var filePath in filePaths) // { // // 检查文件是否已经存在于数据库 // if (!DBStand.IsSrcImageExitInStand(filePath, CurStandItem.StandId)) // { // // 插入文件路径到数据库 // //InsertFileToDatabase(filePath); // TStandDetail standDetail = new TStandDetail() // { // StandDetailId = Guid.NewGuid().ToString(), // CreateTime = ThisApp.GetNowTime_yyyyMMddHHmmss(), // StandId = CurStandItem.StandId, // SrcImage = filePath, // StandValue = "" // }; // bool blInsert = DBStand.InsertStandDetail(standDetail); // if(blInsert) // { // insertCount++; // } // } // // 更新进度条 // currentFile++; // Application.Current.Dispatcher.Invoke(() => // { // UpdateProgress(progressDialog, currentFile, totalFiles); // }); // } // }); // } // catch(Exception ex) // { // MessageBox.Show(Application.Current.MainWindow, $"插入数据失败:{ex.Message}。", "错误", // MessageBoxButton.OK, MessageBoxImage.Error); // } // return insertCount > 0; //} 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 (StandDetailPage.PageNumber < StandDetailPage.PageCount) { StandDetailPage.PageNumber += 1; LoadStandDetailItemList(); } } catch { } finally { _semaphore.Release(); } } public void PrePage() { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { if (StandDetailPage.PageNumber > 1) { StandDetailPage.PageNumber -= 1; LoadStandDetailItemList(); } } catch { } finally { _semaphore.Release(); } } public void FirstPage() { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { if (StandDetailPage.PageNumber > 1) { StandDetailPage.PageNumber = 1; LoadStandDetailItemList(); } } catch { } finally { _semaphore.Release(); } } public void LastPage() { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { if (StandDetailPage.PageNumber < StandDetailPage.PageCount) { StandDetailPage.PageNumber = StandDetailPage.PageCount; LoadStandDetailItemList(); } } catch { } finally { _semaphore.Release(); } } public void SpeciPage(int pageNumber) { if (!_semaphore.Wait(0)) return; // 防止重复调用 try { if (pageNumber != StandDetailPage.PageNumber && pageNumber > 0 && pageNumber <= StandDetailPage.PageCount) { StandDetailPage.PageNumber = pageNumber; LoadStandDetailItemList(); } } catch { } finally { _semaphore.Release(); } } 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; //获取当前行绑定的数据项 var selectedItem = row.Item as StandDetailItem; DeleteSelectedItem(selectedItem); } private async void DeleteSelectedItem(StandDetailItem 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 = DBStand.DeleteTStandDetailById(selectedItem.StandDetailId); }); if (deleteSuccess) { //LoadStandDetailItemList(CurStandItem); //await Application.Current.Dispatcher.BeginInvoke(new Action(() => //{ // 从数据源中移除该条目 StandDetailList.Remove(selectedItem); SelectedStandDetailItem = null; OnDeleteStandDetailItem?.Invoke(selectedItem.StandId); //重新加载数据 //LoadPatchDetailItemList(); //})); } } 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 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 StandDetailItem; UpdateStandvalue(selectedItem); } private void MiDelteRow_Click(object sender, RoutedEventArgs e) { if(SelectedStandDetailItem != null) { DeleteSelectedItem(SelectedStandDetailItem); } } private void MiUpdateStandvalue_Click(object sender, RoutedEventArgs e) { if (SelectedStandDetailItem == null) return; UpdateStandvalue(SelectedStandDetailItem); } 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; //获取当前行绑定的数据项 var selectedItem = row.Item as StandDetailItem; EditStandDetailCfg dialog = new EditStandDetailCfg(selectedItem) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner }; if (dialog.ShowDialog() == true) { selectedItem = dialog.mStandDetail; OnStandDetailMark?.Invoke(selectedItem.StandId, selectedItem.StandId); } } 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; } /////////////////////////////////////////////////////////////////////////// } public class StandDetailItemChangedEventArgs : EventArgs { public StandDetailItem SelectedDataItem { get; } public StandDetailItemChangedEventArgs(StandDetailItem selectedDataItem) { SelectedDataItem = selectedDataItem; } } //目录的条目数发生了变化 //public class StandItemCountChangedEventArgs : EventArgs //{ // public StandItem mStandItem { get; } // public StandItemCountChangedEventArgs(StandItem standItem) // { // mStandItem = standItem; // } //} /////////////////////////////////////////////////////////////////// }