331 lines
10 KiB
C#
331 lines
10 KiB
C#
|
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<ScanCableModel> 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<FlexBaseOrganizer>.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<DatTreeNodeEx<BaseOccurrence>> nodeByEntity = this._occTreeView.GetNodeByEntity(baseOccurrence);
|
|||
|
if (nodeByEntity != null)
|
|||
|
{
|
|||
|
foreach (DatTreeNodeEx<BaseOccurrence> 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<string, List<string>> _errors = new Dictionary<string, List<string>>();
|
|||
|
|
|||
|
public bool HasErrors => _errors.Any();
|
|||
|
|
|||
|
public event EventHandler<DataErrorsChangedEventArgs> 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<string>();
|
|||
|
}
|
|||
|
|
|||
|
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
|
|||
|
}
|
|||
|
}
|