633 lines
20 KiB
C#
633 lines
20 KiB
C#
using EPLAN.Harness.API;
|
|
using EPLAN.Harness.Common;
|
|
using EPLAN.Harness.Core.Controls;
|
|
using EPLAN.Harness.ProjectCore;
|
|
using EPLAN.Harness.ProjectCore.Occurrences;
|
|
using EPLAN.Harness.ProjectCore.Occurrences.Designer;
|
|
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.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; } = [];
|
|
|
|
|
|
public ObservableCollection<ScanCableModel> _ScanCableModels
|
|
{
|
|
get => ScanCableModels;
|
|
set
|
|
{
|
|
if (ScanCableModels != value)
|
|
{
|
|
ScanCableModels = value;
|
|
|
|
OnPropertyChanged(nameof(_ScanCableModels));
|
|
}
|
|
}
|
|
}
|
|
|
|
#region
|
|
private string _S_part;
|
|
public string S_part
|
|
{
|
|
get => _S_part;
|
|
set
|
|
{
|
|
_S_part = value;
|
|
|
|
OnPropertyChanged(nameof(S_part));
|
|
}
|
|
}
|
|
|
|
private string _E_part;
|
|
public string E_part
|
|
{
|
|
get => _E_part;
|
|
set
|
|
{
|
|
_E_part = value;
|
|
|
|
OnPropertyChanged(nameof(E_part));
|
|
}
|
|
}
|
|
|
|
private string _S_pin;
|
|
public string S_pin
|
|
{
|
|
get => _S_pin;
|
|
set
|
|
{
|
|
_S_pin = value;
|
|
|
|
OnPropertyChanged(nameof(S_pin));
|
|
}
|
|
}
|
|
|
|
private string _E_pin;
|
|
public string E_pin
|
|
{
|
|
get => _E_pin;
|
|
set
|
|
{
|
|
_E_pin = value;
|
|
|
|
OnPropertyChanged(nameof(E_pin));
|
|
}
|
|
}
|
|
|
|
private string _Name;
|
|
public string Name
|
|
{
|
|
get => _Name;
|
|
set
|
|
{
|
|
_Name = value;
|
|
|
|
OnPropertyChanged(nameof(Name));
|
|
}
|
|
}
|
|
private string _Code;
|
|
public string Code
|
|
{
|
|
get => _Code;
|
|
set
|
|
{
|
|
_Code = value;
|
|
|
|
OnPropertyChanged(nameof(Code));
|
|
}
|
|
}
|
|
|
|
private string _Length;
|
|
public string Length
|
|
{
|
|
get => _Length;
|
|
set
|
|
{
|
|
_Length = value;
|
|
|
|
OnPropertyChanged(nameof(Length));
|
|
}
|
|
}
|
|
private string _Imprint;
|
|
public string Imprint
|
|
{
|
|
get => _Imprint;
|
|
set
|
|
{
|
|
_Imprint = value;
|
|
|
|
OnPropertyChanged(nameof(Imprint));
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
private DispatcherTimer _debounceTimer;
|
|
|
|
public ScannerViewModel()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public void GetAllCables()
|
|
{
|
|
ScanCableModels.Clear();
|
|
string s_pinid = "";
|
|
string e_pinid = "";
|
|
_currentFlexDesigner.GetOrganizerOccurrences().ToList().ForEach(occ =>
|
|
{
|
|
if (occ is OccWire wire)
|
|
{
|
|
if (wire.Name.StartsWith("w_", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
|
|
//获取线两端管脚id,id唯一
|
|
var wire_pin = wire.DBG_GetPins.Split(';');
|
|
if (wire_pin.Length != 0)
|
|
{
|
|
s_pinid = wire_pin[0].Substring(1, 32);
|
|
e_pinid = wire_pin[1].Trim().Substring(1, 32);
|
|
}
|
|
|
|
|
|
//保存线材基础属性
|
|
ScanCableModels.Add(new ScanCableModel()
|
|
{
|
|
Index = ScanCableModels.Count + 1,
|
|
Id = wire.ID,
|
|
S_Pin = wire.ConnectedPinsUI.Substring(0, wire.ConnectedPinsUI.IndexOf("<>")),
|
|
E_Pin = wire.ConnectedPinsUI.Substring(wire.ConnectedPinsUI.IndexOf("<>") + 3, wire.ConnectedPinsUI.Length - wire.ConnectedPinsUI.IndexOf("<>") - 3),
|
|
S_pinID = s_pinid,
|
|
E_pinID = e_pinid,
|
|
Name = wire.LibraryName,
|
|
Length = Math.Ceiling(wire.Length_VH.GetValueInUnit(UNIT_CLASS.LENGTH)).ToString(),
|
|
Code = wire.Name,
|
|
Imprint = wire.Imprint
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
/// <summary>
|
|
/// scaninfo界面数据 和找到管脚上级部件
|
|
/// </summary>
|
|
/// <param name="scanCableModel"></param>
|
|
public void GetWireConnectPart(ScanCableModel scanCableModel)
|
|
{
|
|
try
|
|
{
|
|
S_pin = scanCableModel.E_Pin;
|
|
E_pin = scanCableModel.E_Pin;
|
|
|
|
Length = scanCableModel.Length;
|
|
Name = scanCableModel.Name;
|
|
Code = scanCableModel.Code;
|
|
Imprint = scanCableModel.Imprint;
|
|
_currentFlexDesigner.GetOrganizerOccurrences().ToList().ForEach(occ =>
|
|
{
|
|
//if (occ is OccConnector Assembly)
|
|
//{
|
|
//var Assembly = occ;
|
|
//根据管脚id获取上级部件信息
|
|
if (occ.ID.Equals(scanCableModel.S_pinID))
|
|
{
|
|
var oriOcc = SelfControler<BaseOccurrence>.FindInstance(occ.ID);
|
|
var parent = oriOcc.Parents?.FirstOrDefault();
|
|
var grandparent = parent.Parents?.FirstOrDefault();
|
|
scanCableModel.S_partObj = grandparent;
|
|
scanCableModel.S_PartID = grandparent.ID;
|
|
scanCableModel.S_part = grandparent.Name;
|
|
S_part = scanCableModel.S_part;
|
|
}
|
|
if (occ.ID.Equals(scanCableModel.E_pinID))
|
|
{
|
|
var oriOcc = SelfControler<BaseOccurrence>.FindInstance(occ.ID);
|
|
var parent = oriOcc.Parents?.FirstOrDefault();
|
|
var grandparent = parent.Parents?.FirstOrDefault();
|
|
scanCableModel.E_partObj = grandparent;
|
|
scanCableModel.E_PartID = grandparent.ID;
|
|
scanCableModel.E_part = grandparent.Name;
|
|
E_part = scanCableModel.E_part;
|
|
}
|
|
|
|
//}
|
|
}
|
|
);
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
FlexMessageBox.Error(ex.Message);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 获取当前设计器
|
|
/// </summary>
|
|
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);
|
|
}
|
|
/// <summary>
|
|
/// 扫描条码(印记/名称)
|
|
/// </summary>
|
|
/// <param name="searchText"></param>
|
|
private void PerformSearch(string searchText)
|
|
{
|
|
// 清除错误信息
|
|
ClearErrors(nameof(InputCode));
|
|
var cable = ScanCableModels.FirstOrDefault(c => c.Code.Equals(searchText, StringComparison.OrdinalIgnoreCase) || c.Imprint.StartsWith(searchText, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
|
if (cable != null)
|
|
{
|
|
// 处理其他线是否隐藏
|
|
OthersOccShow(!OthersWireShow);
|
|
if (_continueScan)
|
|
{
|
|
// 清空输入框
|
|
_enableEvent = false;
|
|
InputCode = string.Empty;
|
|
_enableEvent = true;
|
|
}
|
|
// 扫描即装配
|
|
if (ScanAndAssembled)
|
|
{
|
|
cable.IsChecked = true;
|
|
_ScanCableModels.Remove(cable);
|
|
_ScanCableModels.Insert(0, cable);
|
|
|
|
}
|
|
GetWireConnectPart(cable);
|
|
ScanedIndex = 0;//Math.Max(cable.Index - 1, 0);
|
|
ToSourceById(cable);
|
|
|
|
}
|
|
else
|
|
{
|
|
// 添加错误信息
|
|
AddError(nameof(InputCode), "该条码不存在于列表中");
|
|
}
|
|
}
|
|
|
|
//public void sethightlight()
|
|
//{
|
|
// ClearHighlights();
|
|
// var selectedObjects = HarnessApp.Selection.GetSelectedObjects();
|
|
// foreach (var obj in selectedObjects)
|
|
// {
|
|
// obj.SetHighlight(true); // 高亮选中部件
|
|
// }
|
|
//}
|
|
|
|
//private void ClearHighlights()
|
|
//{
|
|
// var allObjects = HarnessApp.GetAllObjects();
|
|
// foreach (var obj in allObjects)
|
|
// {
|
|
// obj.SetHighlight(false); // 清除高亮
|
|
// }
|
|
//}
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 将设计器聚焦到对应的线
|
|
/// </summary>
|
|
/// <param name="occId"></param>
|
|
public void ToSourceById(string occId)
|
|
{
|
|
// 从设计器中获取线实例
|
|
var occWire = _currentFlexDesigner.GetOccurrenceByID(occId);
|
|
|
|
var scanedWire = ScanCableModels.FirstOrDefault();
|
|
if (occWire != null)
|
|
{
|
|
// 设置线显示
|
|
occWire.SetVisibility(true, null);
|
|
// 清空已选择项并加入当前线
|
|
_currentFlexDesigner.SelectSet.Clear();
|
|
_currentFlexDesigner.SelectSet.Add(occWire);
|
|
if (occId.Equals(scanedWire.S_PartID)|| occId.Equals(scanedWire.S_pinID) )
|
|
_currentFlexDesigner.SelectSet.Add(scanedWire.S_partObj.Children.Where(it => it.Type == OCC_TYPE.wPART));
|
|
else
|
|
_currentFlexDesigner.SelectSet.Add(scanedWire.E_partObj.Children.Where(it => it.Type == OCC_TYPE.wPART));
|
|
|
|
// 缩放设计器且触发选中事件
|
|
_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);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 将设计器聚焦到对应的线
|
|
/// </summary>
|
|
/// <param name="occId"></param>
|
|
public void ToSourceById(ScanCableModel scanedWire)
|
|
{
|
|
var occId = scanedWire.Id;
|
|
// 从设计器中获取线实例
|
|
var occWire = _currentFlexDesigner.GetOccurrenceByID(occId);
|
|
if (occWire != null)
|
|
{
|
|
// 设置线显示
|
|
occWire.SetVisibility(true, null);
|
|
// 清空已选择项并加入当前线
|
|
_currentFlexDesigner.SelectSet.Clear();
|
|
_currentFlexDesigner.SelectSet.Add(scanedWire.S_partObj.Children.Where(it => it.Type == OCC_TYPE.wPART));
|
|
_currentFlexDesigner.SelectSet.Add(scanedWire.E_partObj.Children.Where(it => it.Type == OCC_TYPE.wPART));
|
|
_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)
|
|
{
|
|
// 获取设计器中所有的Occurrence
|
|
_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
|
|
}
|
|
}
|