EPLAN_PROD_Plugin/Sinvo.EplanHpD.Plugin.WPFUI/ViewModel/Scanner/ScannerViewModel.cs

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
}
}