using CommunityToolkit.Mvvm.Messaging; using EPLAN.Harness.API; using EPLAN.Harness.AppCore.StudioCommon.TreeView; using EPLAN.Harness.Core.Controls; using EPLAN.Harness.Primitives.Treeviews; using EPLAN.Harness.ProjectCore; using EPLAN.Harness.ProjectCore.Occurrences.Designer; using Sinvo.EplanHpD.Plugin.WPFUI.Common; using Sinvo.EplanHpD.Plugin.WPFUI.Models; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using System.Windows.Threading; namespace Sinvo.EplanHpD.Plugin.WPFUI.ViewModel { public class ScannerViewModel : INotifyPropertyChanged, INotifyDataErrorInfo { private FlexDesigner _currentFlexDesigner; private bool _othersWireShow = true; private bool _continueScan = true; private bool _enableEvent = true; private bool _isIncludeAnnotation = true; private bool _scanAndAssembled = true; private int _scanedIndex = 1; public int ScanedIndex { get => _scanedIndex; set { _scanedIndex = value; OnPropertyChanged(nameof(ScanedIndex)); WeakReferenceMessenger.Default.Send(new CommonMessage(value), "ScanedIndexChanged"); } } private string _inputCode; public string InputCode { get => _inputCode; set { if (_inputCode != value) { _inputCode = value; OnPropertyChanged(nameof(InputCode)); if (_enableEvent) { if (_debounceTimer == null) { _debounceTimer = new DispatcherTimer(); _debounceTimer.Interval = TimeSpan.FromMilliseconds(1000); _debounceTimer.Tick += DebounceTimer_Tick; } _debounceTimer.Stop(); _debounceTimer.Start(); } } } } public ObservableCollection ScanCableModels { get; set; } = []; private DispatcherTimer _debounceTimer; public ScannerViewModel() { } public void GetAllCables() { ScanCableModels.Clear(); _currentFlexDesigner.GetOrganizerOccurrences().ToList().ForEach(occ => { if (occ is OccWire wire) { if (wire.Name.StartsWith("w_", StringComparison.OrdinalIgnoreCase)) { ScanCableModels.Add(new ScanCableModel() { Index = ScanCableModels.Count + 1, Name = wire.LibraryName, Code = wire.Name, Imprint = wire.Imprint }); } } }); } public void GetCurrentDoc() { try { HpdApi api = HpdApi.GetInstance(); var currentDocId = api.CurrentProject.GetActiveDocument()?.ID; var designer = SelfControler.FindInstance(currentDocId) as FlexDesigner; if (designer != null) { _currentFlexDesigner = designer; } else { FlexMessageBox.Warning("未找到当前打开的工作区,请先打开工作区"); } } catch (Exception ex) { FlexMessageBox.Error(ex.Message); } } private void DebounceTimer_Tick(object sender, EventArgs e) { _debounceTimer.Stop(); string searchText = InputCode; PerformSearch(searchText); } private void PerformSearch(string searchText) { // 清除错误信息 ClearErrors(nameof(InputCode)); var cable = ScanCableModels.FirstOrDefault(c => c.Code.Equals(searchText, StringComparison.OrdinalIgnoreCase)); if (cable != null) { OthersOccShow(!OthersWireShow); if (_continueScan) { _enableEvent = false; InputCode = string.Empty; _enableEvent = true; } if (ScanAndAssembled) { cable.IsChecked = true; } ScanedIndex = Math.Max(cable.Index - 1, 0); ToSourceByName(searchText); } else { // 添加错误信息 AddError(nameof(InputCode), "该条码不存在于列表中"); } } private void ToSourceByName(string wireName) { var occWire = _currentFlexDesigner.GetOccurrenceByName(wireName, typeof(OccWire)); if (occWire != null) { occWire.SetVisibility(true, null); _currentFlexDesigner.SelectSet.Clear(); _currentFlexDesigner.SelectSet.Add(occWire); _currentFlexDesigner.FitToSelectSet(); _currentFlexDesigner.SelectSet.OnSelectionChanged(); //_currentFlexDesigner.Camera.GraphicControl._HighlightNode() /* List> nodeByEntity = this._occTreeView.GetNodeByEntity(baseOccurrence); if (nodeByEntity != null) { foreach (DatTreeNodeEx datTreeNodeEx in nodeByEntity) { if (!this._occTreeView.SelectedNodes.Contains(datTreeNodeEx)) { this._occTreeView.SelectedNodes.Add(datTreeNodeEx); } } } */ } } public void OthersOccShow(bool show = false) { _currentFlexDesigner.GetOrganizerOccurrences().ToList().ForEach(occ => { if (occ is OccWire wire) { wire.SetVisibility(show, null); } if (occ is OccCableForked cable) { cable.SetVisibility(show, null); } if (_isIncludeAnnotation) { if (occ is OccAnnotation annotation) { Debug.WriteLine($"BaseOccurrence -> {annotation.Name} Type: {annotation.GetType().Name}"); annotation.SetVisibility(show, null); } } }); if (show) { _currentFlexDesigner.FitToSelectSet(); } } // 添加属性以绑定界面上的控件,例如复选框等 public bool OthersWireShow { get => _othersWireShow; set { if (_othersWireShow != value) { _othersWireShow = value; OnPropertyChanged(nameof(OthersWireShow)); } } } public bool ContinueScan { get => _continueScan; set { if (_continueScan != value) { _continueScan = value; OnPropertyChanged(nameof(ContinueScan)); } } } public bool IsIncludeAnnotation { get => _isIncludeAnnotation; set { if (_isIncludeAnnotation != value) { _isIncludeAnnotation = value; OnPropertyChanged(nameof(IsIncludeAnnotation)); } } } public bool ScanAndAssembled { get => _scanAndAssembled; set { if (_scanAndAssembled != value) { _scanAndAssembled = value; OnPropertyChanged(nameof(ScanAndAssembled)); } } } public void ExportWires(string path) { MiniExcelLibs.MiniExcel.SaveAs(path, ScanCableModels.Select(it => new { 序号 = it.Index, 导线名称 = it.Code, 导线型号 = it.Name, 导线是否已扫描 = it.IsChecked ? "是" : "否" })); } #region Notify // 实现 INotifyPropertyChanged 接口 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } // 实现 INotifyDataErrorInfo 接口 private readonly Dictionary> _errors = new Dictionary>(); public bool HasErrors => _errors.Any(); public event EventHandler ErrorsChanged; public IEnumerable GetErrors(string propertyName) { if (string.IsNullOrEmpty(propertyName)) return null; _errors.TryGetValue(propertyName, out var errorsForName); return errorsForName; } protected void OnErrorsChanged(string propertyName) { ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName)); } private void AddError(string propertyName, string error) { if (!_errors.ContainsKey(propertyName)) { _errors[propertyName] = new List(); } if (!_errors[propertyName].Contains(error)) { _errors[propertyName].Add(error); OnErrorsChanged(propertyName); } } private void ClearErrors(string propertyName) { if (_errors.ContainsKey(propertyName)) { _errors.Remove(propertyName); OnErrorsChanged(propertyName); } } #endregion } }