添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
public enum CylinderControlType
|
||||
{
|
||||
SingleOutput = 0,
|
||||
DualOutput = 1,
|
||||
MultiOutput = 2
|
||||
}
|
||||
|
||||
public enum CylinderConditionType
|
||||
{
|
||||
PointOn = 0,
|
||||
PointOff = 1
|
||||
}
|
||||
|
||||
public class CylinderActionConditionDefinition
|
||||
{
|
||||
public CylinderConditionType ConditionType { get; set; }
|
||||
public string PointReference { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
||||
public bool ExpectedState => ConditionType == CylinderConditionType.PointOn;
|
||||
}
|
||||
|
||||
public class CylinderDefinition
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Module { get; set; }
|
||||
public CylinderControlType ControlType { get; set; }
|
||||
public List<string> ExtendOutputPoints { get; set; } = new List<string>();
|
||||
public List<string> RetractOutputPoints { get; set; } = new List<string>();
|
||||
public List<string> ExtendedFeedbackPoints { get; set; } = new List<string>();
|
||||
public List<string> RetractedFeedbackPoints { get; set; } = new List<string>();
|
||||
public List<CylinderActionConditionDefinition> ExtendConditions { get; set; } = new List<CylinderActionConditionDefinition>();
|
||||
public List<CylinderActionConditionDefinition> RetractConditions { get; set; } = new List<CylinderActionConditionDefinition>();
|
||||
|
||||
public bool HasRetractOutputs => RetractOutputPoints != null && RetractOutputPoints.Count > 0;
|
||||
}
|
||||
|
||||
public class CylinderExecutionResult
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string FailureReason { get; set; }
|
||||
public IReadOnlyList<string> FailurePointReferences { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
public static class CylinderDefinitionLoader
|
||||
{
|
||||
private const string CylinderConfigFileName = "CylinderDefinitions.csv";
|
||||
|
||||
public static IReadOnlyList<CylinderDefinition> LoadDefinitions()
|
||||
{
|
||||
var definitions = new List<CylinderDefinition>();
|
||||
var path = ResolveConfigPath();
|
||||
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
||||
{
|
||||
return definitions;
|
||||
}
|
||||
|
||||
var lines = File.ReadAllLines(path, Encoding.UTF8);
|
||||
foreach (var raw in lines)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(raw))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var line = raw.Trim();
|
||||
if (line.StartsWith("#") || line.StartsWith("Name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var cols = line.Split(',');
|
||||
if (cols.Length < 7)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var extendOutputPoints = ParsePointReferences(cols[3]);
|
||||
if (extendOutputPoints.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var retractOutputPoints = ParsePointReferences(cols[4]);
|
||||
|
||||
var hasConditionColumns = cols.Length >= 10;
|
||||
var extendConditionIndex = hasConditionColumns ? 7 : -1;
|
||||
var retractConditionIndex = hasConditionColumns ? 8 : -1;
|
||||
var descriptionIndex = hasConditionColumns ? 9 : 7;
|
||||
|
||||
definitions.Add(new CylinderDefinition
|
||||
{
|
||||
Name = cols[0].Trim(),
|
||||
Module = cols[1].Trim(),
|
||||
ControlType = ParseControlType(cols[2]),
|
||||
ExtendOutputPoints = extendOutputPoints,
|
||||
RetractOutputPoints = retractOutputPoints,
|
||||
ExtendedFeedbackPoints = ParsePointReferences(cols[5]),
|
||||
RetractedFeedbackPoints = ParsePointReferences(cols[6]),
|
||||
ExtendConditions = extendConditionIndex >= 0 ? ParseConditions(cols[extendConditionIndex]) : new List<CylinderActionConditionDefinition>(),
|
||||
RetractConditions = retractConditionIndex >= 0 ? ParseConditions(cols[retractConditionIndex]) : new List<CylinderActionConditionDefinition>(),
|
||||
Description = cols.Length > descriptionIndex ? string.Join(",", cols.Skip(descriptionIndex)).Trim() : string.Empty
|
||||
});
|
||||
}
|
||||
|
||||
return definitions;
|
||||
}
|
||||
|
||||
private static CylinderControlType ParseControlType(string raw)
|
||||
{
|
||||
if (string.Equals(raw, "DualOutput", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(raw, "Dual", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CylinderControlType.DualOutput;
|
||||
}
|
||||
|
||||
if (string.Equals(raw, "MultiOutput", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(raw, "Multi", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CylinderControlType.MultiOutput;
|
||||
}
|
||||
|
||||
return CylinderControlType.SingleOutput;
|
||||
}
|
||||
|
||||
private static List<string> ParsePointReferences(string raw)
|
||||
{
|
||||
return (raw ?? string.Empty)
|
||||
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(x => x.Trim())
|
||||
.Where(x => !string.IsNullOrWhiteSpace(x))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static List<CylinderActionConditionDefinition> ParseConditions(string raw)
|
||||
{
|
||||
return (raw ?? string.Empty)
|
||||
.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(ParseCondition)
|
||||
.Where(x => x != null)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static CylinderActionConditionDefinition ParseCondition(string raw)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(raw))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var parts = raw.Split(new[] { ':' }, 3);
|
||||
if (parts.Length < 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var pointReference = parts[1].Trim();
|
||||
if (string.IsNullOrWhiteSpace(pointReference))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
CylinderConditionType conditionType;
|
||||
switch ((parts[0] ?? string.Empty).Trim().ToUpperInvariant())
|
||||
{
|
||||
case "POINTON":
|
||||
case "ON":
|
||||
conditionType = CylinderConditionType.PointOn;
|
||||
break;
|
||||
case "POINTOFF":
|
||||
case "OFF":
|
||||
conditionType = CylinderConditionType.PointOff;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CylinderActionConditionDefinition
|
||||
{
|
||||
ConditionType = conditionType,
|
||||
PointReference = pointReference,
|
||||
Message = parts.Length > 2 ? parts[2].Trim() : string.Empty
|
||||
};
|
||||
}
|
||||
|
||||
private static string ResolveConfigPath()
|
||||
{
|
||||
var baseDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||
var localPath = Path.Combine(baseDir, "Configuration", CylinderConfigFileName);
|
||||
var sourcePath = ResolveRootConfigPath(baseDir);
|
||||
|
||||
if (TrySyncConfigToLocal(sourcePath, localPath))
|
||||
{
|
||||
return localPath;
|
||||
}
|
||||
|
||||
return File.Exists(localPath) ? localPath : sourcePath;
|
||||
}
|
||||
|
||||
private static string ResolveRootConfigPath(string baseDir)
|
||||
{
|
||||
var current = new DirectoryInfo(baseDir);
|
||||
while (current != null)
|
||||
{
|
||||
var rootConfigDir = Path.Combine(current.FullName, "Configuration");
|
||||
if (Directory.Exists(rootConfigDir) && Directory.Exists(Path.Combine(current.FullName, "MainShell")))
|
||||
{
|
||||
var path = Path.Combine(rootConfigDir, CylinderConfigFileName);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
current = current.Parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool TrySyncConfigToLocal(string sourcePath, string localPath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sourcePath) || !File.Exists(sourcePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.Equals(Path.GetFullPath(sourcePath), Path.GetFullPath(localPath), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var localDir = Path.GetDirectoryName(localPath);
|
||||
if (!string.IsNullOrWhiteSpace(localDir))
|
||||
{
|
||||
Directory.CreateDirectory(localDir);
|
||||
}
|
||||
|
||||
if (!File.Exists(localPath) || File.GetLastWriteTimeUtc(localPath) < File.GetLastWriteTimeUtc(sourcePath))
|
||||
{
|
||||
File.Copy(sourcePath, localPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
public class DeviceMaintanceBaseViewModel : Screen
|
||||
{
|
||||
public event Action<bool> UiStateChangedEvent = null;
|
||||
|
||||
protected void OnUiStateChanged(bool uiStateChanged)
|
||||
{
|
||||
UiStateChangedEvent?.Invoke(uiStateChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using MainShell.Filewritable;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
public class LaserCompensationSetting : MXJM.FileWritable.JsonFileWritableBase, INotifyPropertyChanged
|
||||
{
|
||||
private string _axisName = "Axis_Stage_Y3";
|
||||
public string AxisName
|
||||
{
|
||||
get { return _axisName; }
|
||||
set { SetAndNotify(ref _axisName, value); }
|
||||
}
|
||||
|
||||
private double _startPos;
|
||||
public double StartPos
|
||||
{
|
||||
get { return _startPos; }
|
||||
set { SetAndNotify(ref _startPos, value); }
|
||||
}
|
||||
|
||||
private double _steps = 1.0d;
|
||||
public double Steps
|
||||
{
|
||||
get { return _steps; }
|
||||
set { SetAndNotify(ref _steps, value); }
|
||||
}
|
||||
|
||||
private int _stepsCount = 5;
|
||||
public int StepsCount
|
||||
{
|
||||
get { return _stepsCount; }
|
||||
set { SetAndNotify(ref _stepsCount, value); }
|
||||
}
|
||||
|
||||
private double _jumpPos = 1.0d;
|
||||
public double JumpPos
|
||||
{
|
||||
get { return _jumpPos; }
|
||||
set { SetAndNotify(ref _jumpPos, value); }
|
||||
}
|
||||
|
||||
private int _workCount = 1;
|
||||
public int WorkCount
|
||||
{
|
||||
get { return _workCount; }
|
||||
set { SetAndNotify(ref _workCount, value); }
|
||||
}
|
||||
|
||||
private double _speed = 5.0d;
|
||||
public double Speed
|
||||
{
|
||||
get { return _speed; }
|
||||
set { SetAndNotify(ref _speed, value); }
|
||||
}
|
||||
|
||||
private double _dwellTime = 0.5d;
|
||||
public double DwellTime
|
||||
{
|
||||
get { return _dwellTime; }
|
||||
set { SetAndNotify(ref _dwellTime, value); }
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override string Dir => Paths.CalibSettingPath;
|
||||
|
||||
[JsonIgnore]
|
||||
public override string FileName => "LaserCompensationSetting.json";
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public void LoadFromFile()
|
||||
{
|
||||
Read();
|
||||
}
|
||||
|
||||
public void SaveToFile()
|
||||
{
|
||||
Write();
|
||||
}
|
||||
|
||||
protected bool SetAndNotify<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (Equals(field, value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
field = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Filewritable;
|
||||
using MaxwellControl.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
public enum MaintanceType
|
||||
{
|
||||
针尖维护 = 1,
|
||||
相机校验 = 2,
|
||||
针印验证 = 3,
|
||||
}
|
||||
public class MaintanceRecord
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string DeviceId { get; set; }
|
||||
/// <summary>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
public string DeviceName { get; set; }
|
||||
/// <summary>
|
||||
/// 维护时间
|
||||
/// </summary>
|
||||
public DateTime MaintanceTime { get; set; }
|
||||
/// <summary>
|
||||
/// 维护内容
|
||||
/// </summary>
|
||||
public MaintanceType MaintanceType { get; set; }
|
||||
|
||||
public void WriteToFile(string info)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(Paths.MaintanceRecordDir))
|
||||
{
|
||||
Directory.CreateDirectory(Paths.MaintanceRecordDir);
|
||||
}
|
||||
string filePath = Path.Combine(Paths.MaintanceRecordDir, $"{MaintanceType}_MaintanceRecord.txt");
|
||||
using (var writer = new System.IO.StreamWriter(filePath, true))
|
||||
{
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
writer.WriteLine("设备ID,日期,信息");
|
||||
}
|
||||
writer.WriteLine($"{DeviceId},{DateTime.Now}: {info}");
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"写入文件失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,757 @@
|
||||
using MwFramework.Controls.UIControl;
|
||||
using MwFramework.ManagerService;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
[Export(typeof(IParameter))]
|
||||
public class NeedleCalibrationSetting : ParameterBase
|
||||
{
|
||||
public NeedleZCalibrationItem NeedleZCalibrationItem { get; set; } = new NeedleZCalibrationItem();
|
||||
|
||||
public NeedleXYCalibrationItem NeedleXYCalibrationItem { get; set; } = new NeedleXYCalibrationItem();
|
||||
|
||||
public NeedleXYCalibrationItemNew NeedleXYCalibrationItemNew { get; set; } = new NeedleXYCalibrationItemNew();
|
||||
|
||||
public override void Copy(IParameter source)
|
||||
{
|
||||
NeedleCalibrationSetting setting = source as NeedleCalibrationSetting;
|
||||
if (setting != null)
|
||||
{
|
||||
ReflectionExtension.Copy<NeedleZCalibrationItem>(NeedleZCalibrationItem, setting.NeedleZCalibrationItem);
|
||||
ReflectionExtension.Copy<NeedleXYCalibrationItem>(NeedleXYCalibrationItem, setting.NeedleXYCalibrationItem);
|
||||
ReflectionExtension.Copy<NeedleXYCalibrationItemNew>(NeedleXYCalibrationItemNew, setting.NeedleXYCalibrationItemNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class NeedleZCalibrationItem : PropertyChangedBase, IParameterItem
|
||||
{
|
||||
|
||||
private double _supportPinPositionX;
|
||||
[WatchValue("针尖对准对刀仪X1位置")]
|
||||
public double SupportPinPositionX
|
||||
{
|
||||
get { return _supportPinPositionX; }
|
||||
set { if (_supportPinPositionX != value) { _supportPinPositionX = value; OnPropertyChanged(nameof(SupportPinPositionX)); } }
|
||||
}
|
||||
|
||||
private double _supportPinPositionY;
|
||||
[WatchValue("针尖对准对刀仪Y1位置")]
|
||||
public double SupportPinPositionY
|
||||
{
|
||||
get { return _supportPinPositionY; }
|
||||
set { if (_supportPinPositionY != value) { _supportPinPositionY = value; OnPropertyChanged(nameof(SupportPinPositionY)); } }
|
||||
}
|
||||
|
||||
private double _knifeOffset;
|
||||
[WatchValue("对刀仪偏差")]
|
||||
/// <summary>
|
||||
/// 对刀仪偏差
|
||||
/// </summary>
|
||||
public double KnifeOffset
|
||||
{
|
||||
get { return _knifeOffset; }
|
||||
set { if (_knifeOffset != value) { _knifeOffset = value; OnPropertyChanged(nameof(KnifeOffset)); } }
|
||||
}
|
||||
|
||||
private double _cZHeight = -0.725;
|
||||
[WatchValue("SZ高度")]
|
||||
public double CZHeight
|
||||
{
|
||||
get { return _cZHeight; }
|
||||
set { if (_cZHeight != value) { _cZHeight = value; OnPropertyChanged(nameof(CZHeight)); } }
|
||||
}
|
||||
|
||||
private double _stageHeight;
|
||||
[WatchValue("载台高度")]
|
||||
public double StageHeight
|
||||
{
|
||||
get { return _stageHeight; }
|
||||
set { if (_stageHeight != value) { _stageHeight = value; OnPropertyChanged(nameof(StageHeight)); } }
|
||||
}
|
||||
|
||||
private double _gantry2AvoidPositionX = 10;
|
||||
[WatchValue("对刀时龙门X2的避让位置")]
|
||||
public double Gantry2AvoidPositionX
|
||||
{
|
||||
get { return _gantry2AvoidPositionX; }
|
||||
set { if (_gantry2AvoidPositionX != value) { _gantry2AvoidPositionX = value; OnPropertyChanged(nameof(Gantry2AvoidPositionX)); } }
|
||||
}
|
||||
private double _gantry2AvoidPositionY = 200;
|
||||
[WatchValue("对刀时龙门Y2的避让位置")]
|
||||
public double Gantry2AvoidPositionY
|
||||
{
|
||||
get { return _gantry2AvoidPositionY; }
|
||||
set { if (_gantry2AvoidPositionY != value) { _gantry2AvoidPositionY = value; OnPropertyChanged(nameof(Gantry2AvoidPositionY)); } }
|
||||
}
|
||||
private double _z1StartPosition;
|
||||
[WatchValue("Z1开始位置")]
|
||||
public double Z1StartPosition
|
||||
{
|
||||
get { return _z1StartPosition; }
|
||||
set { if (_z1StartPosition != value) { _z1StartPosition = value; OnPropertyChanged(nameof(Z1StartPosition)); } }
|
||||
}
|
||||
|
||||
private double _z1Speed;
|
||||
[WatchValue("Z1速度")]
|
||||
public double Z1Speed
|
||||
{
|
||||
get { return _z1Speed; }
|
||||
set { if (_z1Speed != value) { _z1Speed = value; OnPropertyChanged(nameof(Z1Speed)); } }
|
||||
}
|
||||
|
||||
private double _z1DropMaxPosition;
|
||||
[WatchValue("Z1下降距离")]
|
||||
public double Z1DropMaxPosition
|
||||
{
|
||||
get { return _z1DropMaxPosition; }
|
||||
set { if (_z1DropMaxPosition != value) { _z1DropMaxPosition = value; OnPropertyChanged(nameof(Z1DropMaxPosition)); } }
|
||||
}
|
||||
|
||||
private int _needleTouchCount = 1;
|
||||
[WatchValue("对刀次数")]
|
||||
public int NeedleTouchCount
|
||||
{
|
||||
get { return _needleTouchCount; }
|
||||
set { if (_needleTouchCount != value) { _needleTouchCount = value; OnPropertyChanged(nameof(NeedleTouchCount)); } }
|
||||
}
|
||||
|
||||
private double _needleTouchHeight = 14;
|
||||
|
||||
/// <summary>
|
||||
/// Z1接触对刀仪高度
|
||||
/// </summary>
|
||||
[WatchValue("Z1接触对刀仪高度")]
|
||||
public double NeedleTouchHeight
|
||||
{
|
||||
get { return _needleTouchHeight; }
|
||||
set { if (_needleTouchHeight != value) { _needleTouchHeight = value; OnPropertyChanged(nameof(NeedleTouchHeight)); } }
|
||||
}
|
||||
|
||||
private double _needleTouchHeightBase;
|
||||
|
||||
/// <summary>
|
||||
/// 基准值
|
||||
/// </summary>
|
||||
[WatchValue("基准值")]
|
||||
public double NeedleTouchHeightBase
|
||||
{
|
||||
get { return _needleTouchHeightBase; }
|
||||
set { if (_needleTouchHeightBase != value) { _needleTouchHeightBase = value; OnPropertyChanged(nameof(NeedleTouchHeightBase)); } }
|
||||
}
|
||||
|
||||
private double _currentNeedleTouchHeight;
|
||||
[WatchValue("当前使用对刀高度")]
|
||||
/// <summary>
|
||||
/// 当前使用对刀高度
|
||||
/// </summary>
|
||||
public double CurrentNeedleTouchHeight
|
||||
{
|
||||
get { return _currentNeedleTouchHeight; }
|
||||
set { if (_currentNeedleTouchHeight != value) { _currentNeedleTouchHeight = value; OnPropertyChanged(nameof(CurrentNeedleTouchHeight)); } }
|
||||
}
|
||||
|
||||
private double _needleTouchOffset;
|
||||
[WatchValue("对刀与基准偏差")]
|
||||
/// <summary>
|
||||
/// 对刀与基准偏差
|
||||
/// </summary>
|
||||
public double NeedleTouchOffset
|
||||
{
|
||||
get { return _needleTouchOffset; }
|
||||
set { if (_needleTouchOffset != value) { _needleTouchOffset = value; OnPropertyChanged(nameof(NeedleTouchOffset)); } }
|
||||
}
|
||||
|
||||
private double _needleTouchHeightAve;
|
||||
[WatchValue("Z1对刀平均高度")]
|
||||
/// <summary>
|
||||
/// Z1对刀平均高度
|
||||
/// </summary>
|
||||
public double NeedleTouchHeightAve
|
||||
{
|
||||
get { return _needleTouchHeightAve; }
|
||||
set { if (_needleTouchHeightAve != value) { _needleTouchHeightAve = value; OnPropertyChanged(nameof(NeedleTouchHeightAve)); } }
|
||||
}
|
||||
|
||||
private ObservableCollection<NeedleTouchRecord> _needleTouchRecords = new ObservableCollection<NeedleTouchRecord>();
|
||||
|
||||
public ObservableCollection<NeedleTouchRecord> NeedleTouchRecords
|
||||
{
|
||||
get { return _needleTouchRecords; }
|
||||
set
|
||||
{
|
||||
_needleTouchRecords = value;
|
||||
OnPropertyChanged(nameof(NeedleTouchRecords));
|
||||
}
|
||||
}
|
||||
|
||||
private double _laserToNeedleOffset = 0;
|
||||
public double LaserToNeedleOffset
|
||||
{
|
||||
get { return _laserToNeedleOffset; }
|
||||
set { if (_laserToNeedleOffset != value) { _laserToNeedleOffset = value; OnPropertyChanged(nameof(LaserToNeedleOffset)); } }
|
||||
}
|
||||
|
||||
private double _needleCameraHeightOffset;
|
||||
public double NeedleCameraHeightOffset
|
||||
{
|
||||
get { return _needleCameraHeightOffset; }
|
||||
set { if (_needleCameraHeightOffset != value) { _needleCameraHeightOffset = value; OnPropertyChanged(nameof(NeedleCameraHeightOffset)); } }
|
||||
}
|
||||
|
||||
public IParameterItem Clone()
|
||||
{
|
||||
NeedleZCalibrationItem clone = new NeedleZCalibrationItem();
|
||||
clone.CurrentNeedleTouchHeight = _needleCameraHeightOffset;
|
||||
clone.CZHeight = CZHeight;
|
||||
clone.Gantry2AvoidPositionX = Gantry2AvoidPositionX;
|
||||
clone.Gantry2AvoidPositionY = Gantry2AvoidPositionY;
|
||||
clone.LaserToNeedleOffset = LaserToNeedleOffset;
|
||||
clone.NeedleCameraHeightOffset = NeedleCameraHeightOffset;
|
||||
clone.NeedleTouchCount = NeedleTouchCount;
|
||||
clone.NeedleTouchHeight = NeedleTouchHeight;
|
||||
clone.NeedleTouchHeightAve = NeedleTouchHeightAve;
|
||||
clone.NeedleTouchHeightBase = NeedleTouchHeightBase;
|
||||
clone.NeedleTouchOffset = NeedleTouchOffset;
|
||||
clone.StageHeight = StageHeight;
|
||||
clone.SupportPinPositionX = SupportPinPositionX;
|
||||
clone.SupportPinPositionY = SupportPinPositionY;
|
||||
clone.Z1DropMaxPosition = Z1DropMaxPosition;
|
||||
clone.Z1Speed = Z1Speed;
|
||||
clone.Z1StartPosition = Z1StartPosition;
|
||||
if (this.NeedleTouchRecords != null)
|
||||
{
|
||||
foreach (var item in this.NeedleTouchRecords)
|
||||
{
|
||||
clone.NeedleTouchRecords.Add(item.Clone() as NeedleTouchRecord);
|
||||
}
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class NeedleXYCalibrationItem : PropertyChangedBase, IParameterItem
|
||||
{
|
||||
private double _needleX;
|
||||
[WatchValue("设置—刺晶头X")]
|
||||
public double NeedleX
|
||||
{
|
||||
get { return _needleX; }
|
||||
set { if (_needleX != value) { _needleX = value; OnPropertyChanged(nameof(NeedleX)); } }
|
||||
}
|
||||
|
||||
private double _needleY;
|
||||
[WatchValue("设置—刺晶头Y")]
|
||||
public double NeedleY
|
||||
{
|
||||
get { return _needleY; }
|
||||
set { if (_needleY != value) { _needleY = value; OnPropertyChanged(nameof(NeedleY)); } }
|
||||
}
|
||||
|
||||
private double _cameraX;
|
||||
[WatchValue("设置—相机X")]
|
||||
public double CameraX
|
||||
{
|
||||
get { return _cameraX; }
|
||||
set { if (_cameraX != value) { _cameraX = value; OnPropertyChanged(nameof(CameraX)); } }
|
||||
}
|
||||
|
||||
private double _cameraY;
|
||||
[WatchValue("设置—相机Y")]
|
||||
public double CameraY
|
||||
{
|
||||
get { return _cameraY; }
|
||||
set { if (_cameraY != value) { _cameraY = value; OnPropertyChanged(nameof(CameraY)); } }
|
||||
}
|
||||
private double _needleZ1 = 0.0;
|
||||
[WatchValue("设置—刺晶头Z1")]
|
||||
public double NeedleZ1
|
||||
{
|
||||
get { return _needleZ1; }
|
||||
set { if (_needleZ1 != value) { _needleZ1 = value; OnPropertyChanged(nameof(NeedleZ1)); } }
|
||||
}
|
||||
|
||||
private double _offsetX;
|
||||
[WatchValue("X方向偏差")]
|
||||
public double OffsetX
|
||||
{
|
||||
get { return _offsetX; }
|
||||
set { if (_offsetX != value) { _offsetX = value; OnPropertyChanged(nameof(OffsetX)); } }
|
||||
}
|
||||
|
||||
private double _offsetY;
|
||||
[WatchValue("Y方向偏差")]
|
||||
public double OffsetY
|
||||
{
|
||||
get { return _offsetY; }
|
||||
set { if (_offsetY != value) { _offsetY = value; OnPropertyChanged(nameof(OffsetY)); } }
|
||||
}
|
||||
|
||||
private double _initialOffsetX;
|
||||
/// <summary>
|
||||
/// 针和相机之间的X初始偏差,不加补偿
|
||||
/// </summary>
|
||||
[WatchValue("X方向初始偏差")]
|
||||
public double InitialOffsetX
|
||||
{
|
||||
get { return _initialOffsetX; }
|
||||
set { if (_initialOffsetX != value) { _initialOffsetX = value; OnPropertyChanged(nameof(InitialOffsetX)); } }
|
||||
}
|
||||
|
||||
private double _initialOffsetY;
|
||||
/// <summary>
|
||||
/// 针和相机之间的Y初始偏差,不加补偿
|
||||
/// </summary>
|
||||
[WatchValue("Y方向初始偏差")]
|
||||
public double InitialOffsetY
|
||||
{
|
||||
get { return _initialOffsetY; }
|
||||
set { if (_initialOffsetY != value) { _initialOffsetY = value; OnPropertyChanged(nameof(InitialOffsetY)); } }
|
||||
}
|
||||
|
||||
private double _compensateX;
|
||||
/// <summary>
|
||||
/// 针和相机之间的X方向偏差补偿
|
||||
/// </summary>
|
||||
[WatchValue("X方向补偿")]
|
||||
public double CompensateX
|
||||
{
|
||||
get { return _compensateX; }
|
||||
set { if (_compensateX != value) { _compensateX = value; OnPropertyChanged(nameof(CompensateX)); } }
|
||||
}
|
||||
|
||||
private double _compensateY;
|
||||
/// <summary>
|
||||
/// 针和相机之间的Y方向偏差补偿
|
||||
/// </summary>
|
||||
[WatchValue("Y方向补偿")]
|
||||
public double CompensateY
|
||||
{
|
||||
get { return _compensateY; }
|
||||
set { if (_compensateY != value) { _compensateY = value; OnPropertyChanged(nameof(CompensateY)); } }
|
||||
}
|
||||
|
||||
private double _offsetXMax;
|
||||
[WatchValue("偏差限制—X偏差最大值")]
|
||||
public double OffsetXMax
|
||||
{
|
||||
get { return _offsetXMax; }
|
||||
set { if (_offsetXMax != value) { _offsetXMax = value; OnPropertyChanged(nameof(OffsetXMax)); } }
|
||||
}
|
||||
|
||||
private double _offsetXMin;
|
||||
[WatchValue("偏差限制—X偏差最小值")]
|
||||
public double OffsetXMin
|
||||
{
|
||||
get { return _offsetXMin; }
|
||||
set { if (_offsetXMin != value) { _offsetXMin = value; OnPropertyChanged(nameof(OffsetXMin)); } }
|
||||
}
|
||||
|
||||
private double _offsetYMax;
|
||||
[WatchValue("偏差限制—Y偏差最大值")]
|
||||
public double OffsetYMax
|
||||
{
|
||||
get { return _offsetYMax; }
|
||||
set { if (_offsetYMax != value) { _offsetYMax = value; OnPropertyChanged(nameof(OffsetYMax)); } }
|
||||
}
|
||||
|
||||
private double _offsetYMin;
|
||||
[WatchValue("偏差限制—Y偏差最小值")]
|
||||
public double OffsetYMin
|
||||
{
|
||||
get { return _offsetYMin; }
|
||||
set { if (_offsetYMin != value) { _offsetYMin = value; OnPropertyChanged(nameof(OffsetYMin)); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扎铜箔时龙门X2避让位置
|
||||
/// </summary>
|
||||
private double _x2AvoidPosition;
|
||||
[WatchValue("扎铜箔时龙门X2避让位置")]
|
||||
public double X2AvoidPosition
|
||||
{
|
||||
get { return _x2AvoidPosition; }
|
||||
set { if (_x2AvoidPosition != value) { _x2AvoidPosition = value; OnPropertyChanged(nameof(X2AvoidPosition)); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扎铜箔时龙门Y2避让位置
|
||||
/// </summary>
|
||||
private double _y2AvoidPosition;
|
||||
[WatchValue("扎铜箔时龙门Y2避让位置")]
|
||||
public double Y2AvoidPosition
|
||||
{
|
||||
get { return _y2AvoidPosition; }
|
||||
set { if (_y2AvoidPosition != value) { _y2AvoidPosition = value; OnPropertyChanged(nameof(Y2AvoidPosition)); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扎铜箔时Stage的位置
|
||||
/// </summary>
|
||||
private double _stagePosition;
|
||||
[WatchValue("扎铜箔时Stage的位置")]
|
||||
public double StagePosition
|
||||
{
|
||||
get { return _stagePosition; }
|
||||
set { if (_stagePosition != value) { _stagePosition = value; OnPropertyChanged(nameof(StagePosition)); } }
|
||||
}
|
||||
|
||||
public IParameterItem Clone()
|
||||
{
|
||||
NeedleXYCalibrationItem clone = new NeedleXYCalibrationItem();
|
||||
clone.NeedleX = this.NeedleX;
|
||||
clone.NeedleY = this.NeedleY;
|
||||
clone.CameraX = this.CameraY;
|
||||
clone.CameraY = this.CameraY;
|
||||
clone.OffsetX = this.OffsetX;
|
||||
clone.OffsetY = this.OffsetY;
|
||||
clone.OffsetXMax = this.OffsetXMax;
|
||||
clone.OffsetXMin = this.OffsetXMin;
|
||||
clone.OffsetYMax = this.OffsetYMax;
|
||||
clone.OffsetYMin = this.OffsetYMin;
|
||||
return this.MemberwiseClone() as IParameterItem;
|
||||
}
|
||||
}
|
||||
|
||||
public class NeedleXYCalibrationItemNew : PropertyChangedBase, IParameterItem
|
||||
{
|
||||
//private VisionParData _needleVisionParData;
|
||||
|
||||
//public VisionParData NeedleVisionParData
|
||||
//{
|
||||
// get { return _needleVisionParData ?? new VisionParData() { Exposure = 2000 }; }
|
||||
// set { SetAndNotify(ref _needleVisionParData, value); }
|
||||
//}
|
||||
|
||||
private double _x1Calib;
|
||||
/// <summary>
|
||||
/// 相机标定位X1
|
||||
/// </summary>
|
||||
[WatchValue("相机标定位X1")]
|
||||
public double X1Calib
|
||||
{
|
||||
get { return _x1Calib; }
|
||||
set { if (_x1Calib != value) { _x1Calib = value; OnPropertyChanged(nameof(X1Calib)); } }
|
||||
}
|
||||
|
||||
private double _x1MechanicalOffset = 0.0;
|
||||
/// <summary>
|
||||
/// 机械X1Offset
|
||||
/// </summary>
|
||||
[WatchValue("机械X1Offset")]
|
||||
public double X1MechanicalOffset
|
||||
{
|
||||
get { return _x1MechanicalOffset; }
|
||||
set { if (_x1MechanicalOffset != value) { _x1MechanicalOffset = value; OnPropertyChanged(nameof(X1MechanicalOffset)); } }
|
||||
}
|
||||
|
||||
private double _wSCalibX2;
|
||||
/// <summary>
|
||||
/// 方片标定位X2
|
||||
/// </summary>
|
||||
[WatchValue("方片标定位X2")]
|
||||
public double WSCalibX2
|
||||
{
|
||||
get { return _wSCalibX2; }
|
||||
set { if (_wSCalibX2 != value) { _wSCalibX2 = value; OnPropertyChanged(nameof(WSCalibX2)); } }
|
||||
}
|
||||
|
||||
private double _wSCalibY2;
|
||||
/// <summary>
|
||||
/// 方片标定位Y2
|
||||
/// </summary>
|
||||
[WatchValue("方片标定位Y2")]
|
||||
public double WSCalibY2
|
||||
{
|
||||
get { return _wSCalibY2; }
|
||||
set { if (_wSCalibY2 != value) { _wSCalibY2 = value; OnPropertyChanged(nameof(WSCalibY2)); } }
|
||||
}
|
||||
|
||||
private double _needleX1;
|
||||
[WatchValue("刺晶头X1")]
|
||||
public double NeedleX1
|
||||
{
|
||||
get { return _needleX1; }
|
||||
set { if (_needleX1 != value) { _needleX1 = value; OnPropertyChanged(nameof(NeedleX1)); } }
|
||||
}
|
||||
|
||||
private double _needleZ1 = 0.0;
|
||||
[WatchValue("刺晶头Z1")]
|
||||
public double NeedleZ1
|
||||
{
|
||||
get { return _needleZ1; }
|
||||
set { if (_needleZ1 != value) { _needleZ1 = value; OnPropertyChanged(nameof(NeedleZ1)); } }
|
||||
}
|
||||
|
||||
private int _z1WorkTime = 0;
|
||||
/// <summary>
|
||||
/// Z1保持下扎时长
|
||||
/// </summary>
|
||||
[WatchValue("Z1保持下扎时长")]
|
||||
public int Z1WorkTime
|
||||
{
|
||||
get { return _z1WorkTime; }
|
||||
set { if (_z1WorkTime != value) { _z1WorkTime = value; OnPropertyChanged(nameof(Z1WorkTime)); } }
|
||||
}
|
||||
|
||||
private double _offsetX;
|
||||
/// <summary>
|
||||
/// 针和相机之间的X初始偏差,不加补偿
|
||||
/// </summary>
|
||||
[WatchValue("X方向偏差")]
|
||||
public double OffsetX
|
||||
{
|
||||
get { return _offsetX; }
|
||||
set { if (_offsetX != value) { _offsetX = value; OnPropertyChanged(nameof(OffsetX)); } }
|
||||
}
|
||||
|
||||
private double _offsetY;
|
||||
/// <summary>
|
||||
/// 针和相机之间的Y初始偏差,不加补偿
|
||||
/// </summary>
|
||||
[WatchValue("Y方向偏差")]
|
||||
public double OffsetY
|
||||
{
|
||||
get { return _offsetY; }
|
||||
set { if (_offsetY != value) { _offsetY = value; OnPropertyChanged(nameof(OffsetY)); } }
|
||||
}
|
||||
|
||||
private double _compensateX;
|
||||
/// <summary>
|
||||
/// 针和相机之间的X方向偏差补偿
|
||||
/// </summary>
|
||||
[WatchValue("X方向补偿")]
|
||||
public double CompensateX
|
||||
{
|
||||
get { return _compensateX; }
|
||||
set { if (_compensateX != value) { _compensateX = value; OnPropertyChanged(nameof(CompensateX)); } }
|
||||
}
|
||||
|
||||
private double _compensateY;
|
||||
/// <summary>
|
||||
/// 针和相机之间的Y方向偏差补偿
|
||||
/// </summary>
|
||||
[WatchValue("Y方向补偿")]
|
||||
public double CompensateY
|
||||
{
|
||||
get { return _compensateY; }
|
||||
set { if (_compensateY != value) { _compensateY = value; OnPropertyChanged(nameof(CompensateY)); } }
|
||||
}
|
||||
|
||||
private double _offsetXMax;
|
||||
[WatchValue("偏差限制—X偏差最大值")]
|
||||
public double OffsetXMax
|
||||
{
|
||||
get { return _offsetXMax; }
|
||||
set { if (_offsetXMax != value) { _offsetXMax = value; OnPropertyChanged(nameof(OffsetXMax)); } }
|
||||
}
|
||||
|
||||
private double _offsetXMin;
|
||||
[WatchValue("偏差限制—X偏差最小值")]
|
||||
public double OffsetXMin
|
||||
{
|
||||
get { return _offsetXMin; }
|
||||
set { if (_offsetXMin != value) { _offsetXMin = value; OnPropertyChanged(nameof(OffsetXMin)); } }
|
||||
}
|
||||
|
||||
private double _offsetYMax;
|
||||
[WatchValue("偏差限制—Y偏差最大值")]
|
||||
public double OffsetYMax
|
||||
{
|
||||
get { return _offsetYMax; }
|
||||
set { if (_offsetYMax != value) { _offsetYMax = value; OnPropertyChanged(nameof(OffsetYMax)); } }
|
||||
}
|
||||
|
||||
private double _offsetYMin;
|
||||
[WatchValue("偏差限制—Y偏差最小值")]
|
||||
public double OffsetYMin
|
||||
{
|
||||
get { return _offsetYMin; }
|
||||
set { if (_offsetYMin != value) { _offsetYMin = value; OnPropertyChanged(nameof(OffsetYMin)); } }
|
||||
}
|
||||
|
||||
private double _wSApproachX2;
|
||||
/// <summary>
|
||||
/// 方片逼近位X2
|
||||
/// </summary>
|
||||
[WatchValue("方片逼近位X2")]
|
||||
public double WSApproachX2
|
||||
{
|
||||
get { return _wSApproachX2; }
|
||||
set { if (_wSApproachX2 != value) { _wSApproachX2 = value; OnPropertyChanged(nameof(WSApproachX2)); } }
|
||||
}
|
||||
|
||||
private double _wSApproachY2;
|
||||
/// <summary>
|
||||
/// 方片逼近位Y2
|
||||
/// </summary>
|
||||
[WatchValue("方片逼近位Y2")]
|
||||
public double WSApproachY2
|
||||
{
|
||||
get { return _wSApproachY2; }
|
||||
set { if (_wSApproachY2 != value) { _wSApproachY2 = value; OnPropertyChanged(nameof(WSApproachY2)); } }
|
||||
}
|
||||
|
||||
private double _stampThreRadius;
|
||||
/// <summary>
|
||||
/// 针印理论半径
|
||||
/// </summary>
|
||||
[WatchValue("针印理论半径")]
|
||||
public double StampThreRadius
|
||||
{
|
||||
get { return _stampThreRadius; }
|
||||
set { if (_stampThreRadius != value) { _stampThreRadius = value; OnPropertyChanged(nameof(StampThreRadius)); } }
|
||||
}
|
||||
|
||||
private double _stampThreErrorRange;
|
||||
/// <summary>
|
||||
/// 针印误差范围
|
||||
/// </summary>
|
||||
[WatchValue("针印误差范围")]
|
||||
public double StampThreErrorRange
|
||||
{
|
||||
get { return _stampThreErrorRange; }
|
||||
set { if (_stampThreErrorRange != value) { _stampThreErrorRange = value; OnPropertyChanged(nameof(StampThreErrorRange)); } }
|
||||
}
|
||||
|
||||
private double _stampMinCircularity;
|
||||
/// <summary>
|
||||
/// 针印最小圆度
|
||||
/// </summary>
|
||||
[WatchValue("针印最小圆度")]
|
||||
public double StampMinCircularity
|
||||
{
|
||||
get { return _stampMinCircularity; }
|
||||
set { if (_stampMinCircularity != value) { _stampMinCircularity = value; OnPropertyChanged(nameof(StampMinCircularity)); } }
|
||||
}
|
||||
|
||||
private double _stampPolarity;
|
||||
/// <summary>
|
||||
/// 针印颜色,0黑1白
|
||||
/// </summary>
|
||||
[WatchValue("针印理论半径")]
|
||||
public double StampPolarity
|
||||
{
|
||||
get { return _stampPolarity; }
|
||||
set { if (_stampPolarity != value) { _stampPolarity = value; OnPropertyChanged(nameof(StampPolarity)); } }
|
||||
}
|
||||
|
||||
private bool _isBlack = false;
|
||||
public bool IsBlack
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isBlack;
|
||||
}
|
||||
set
|
||||
{
|
||||
_isBlack = value;
|
||||
StampPolarityUpdate();
|
||||
OnPropertyChanged(nameof(IsBlack));
|
||||
}
|
||||
}
|
||||
|
||||
public void StampPolarityUpdate()
|
||||
{
|
||||
if (IsBlack)
|
||||
{
|
||||
StampPolarity = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
StampPolarity = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public IParameterItem Clone()
|
||||
{
|
||||
NeedleXYCalibrationItemNew clone = new NeedleXYCalibrationItemNew();
|
||||
clone.NeedleX1 = this.NeedleX1;
|
||||
clone.NeedleZ1 = this.NeedleZ1;
|
||||
clone.WSApproachX2 = this.WSApproachX2;
|
||||
clone.WSApproachY2 = this.WSApproachY2;
|
||||
clone.Z1WorkTime = Z1WorkTime;
|
||||
clone.X1MechanicalOffset = X1MechanicalOffset;
|
||||
clone.X1Calib = X1Calib;
|
||||
clone.WSCalibX2 = WSCalibX2;
|
||||
clone.WSCalibY2 = WSCalibY2;
|
||||
clone.CompensateX = CompensateX;
|
||||
clone.CompensateY = CompensateY;
|
||||
clone.OffsetX = this.OffsetX;
|
||||
clone.OffsetY = this.OffsetY;
|
||||
clone.OffsetXMax = this.OffsetXMax;
|
||||
clone.OffsetXMin = this.OffsetXMin;
|
||||
clone.OffsetYMax = this.OffsetYMax;
|
||||
clone.OffsetYMin = this.OffsetYMin;
|
||||
clone.IsBlack = this.IsBlack;
|
||||
clone.StampMinCircularity = this.StampMinCircularity;
|
||||
clone.StampPolarity = this.StampPolarity;
|
||||
clone.StampThreErrorRange = this.StampThreErrorRange;
|
||||
clone.StampThreRadius = this.StampThreRadius;
|
||||
|
||||
|
||||
//clone.NeedleVisionParData.Exposure = this.NeedleVisionParData.Exposure;
|
||||
//clone.NeedleVisionParData.Gain = this.NeedleVisionParData.Gain;
|
||||
//clone.NeedleVisionParData.LightSourceBack = this.NeedleVisionParData.LightSourceBack;
|
||||
//clone.NeedleVisionParData.LightSourcePointBlue = this.NeedleVisionParData.LightSourcePointBlue;
|
||||
//clone.NeedleVisionParData.LightSourcePointRed = this.NeedleVisionParData.LightSourcePointRed;
|
||||
//clone.NeedleVisionParData.LightSourceRingBlue = this.NeedleVisionParData.LightSourceRingBlue;
|
||||
//clone.NeedleVisionParData.LightSourceRingRed = this.NeedleVisionParData.LightSourceRingRed;
|
||||
//clone.NeedleVisionParData.Z2 = this.NeedleVisionParData.Z2;
|
||||
|
||||
return this.MemberwiseClone() as IParameterItem;
|
||||
}
|
||||
}
|
||||
|
||||
public class NeedleTouchRecord : PropertyChangedBase, IParameterItem
|
||||
{
|
||||
|
||||
private int _CurrentCount;
|
||||
/// <summary>
|
||||
/// 当前次数
|
||||
/// </summary>
|
||||
public int CurrentCount
|
||||
{
|
||||
get { return _CurrentCount; }
|
||||
set
|
||||
{ SetAndNotify(ref _CurrentCount, value); }
|
||||
}
|
||||
|
||||
private double _Height;
|
||||
/// <summary>
|
||||
/// 高度
|
||||
/// </summary>
|
||||
public double Height
|
||||
{
|
||||
get { return _Height; }
|
||||
set
|
||||
{ SetAndNotify(ref _Height, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public NeedleTouchRecord()
|
||||
{
|
||||
|
||||
}
|
||||
public NeedleTouchRecord(int count, double height)
|
||||
{
|
||||
CurrentCount = count;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public IParameterItem Clone()
|
||||
{
|
||||
return this.MemberwiseClone() as IParameterItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using MainShell.Models;
|
||||
using MwFramework.ManagerService;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.Model
|
||||
{
|
||||
[Export(typeof(IParameter))]
|
||||
public class NeedlePrintCalibrateSetting : ParameterBase
|
||||
{
|
||||
public NeedlePrintCalibrateParameter NeedlePrintCalibrateParameter { get; set; } = new NeedlePrintCalibrateParameter();
|
||||
public NeedlePrintCalibrateSetting() { }
|
||||
public override void Copy(IParameter source)
|
||||
{
|
||||
if (source is NeedlePrintCalibrateSetting setting)
|
||||
{
|
||||
ReflectionExtension.Copy(NeedlePrintCalibrateParameter, setting.NeedlePrintCalibrateParameter);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class NeedlePrintCalibrateParameter : PropertyChangedBase, IParameterItem
|
||||
{
|
||||
private MPoint _startPoint = new MPoint();
|
||||
public MPoint StartPoint
|
||||
{
|
||||
get { return _startPoint; }
|
||||
set { SetAndNotify(ref _startPoint, value); }
|
||||
}
|
||||
|
||||
private MPoint _endPoint = new MPoint();
|
||||
public MPoint EndPoint
|
||||
{
|
||||
get { return _endPoint; }
|
||||
set { SetAndNotify(ref _endPoint, value); }
|
||||
}
|
||||
|
||||
private MPoint _avoidancePoint = new MPoint();
|
||||
|
||||
public MPoint AvoidancePoint
|
||||
{
|
||||
get { return _avoidancePoint; }
|
||||
set { SetAndNotify(ref _avoidancePoint, value); }
|
||||
}
|
||||
|
||||
private double _z1WorkHeight;
|
||||
|
||||
public double Z1WorkHeight
|
||||
{
|
||||
get { return _z1WorkHeight; }
|
||||
set { SetAndNotify(ref _z1WorkHeight, value); }
|
||||
}
|
||||
|
||||
private double _z2WorkHeight;
|
||||
|
||||
public double Z2WorkHeight
|
||||
{
|
||||
get { return _z2WorkHeight; }
|
||||
set { SetAndNotify(ref _z2WorkHeight, value); }
|
||||
}
|
||||
|
||||
private double _xPitch;
|
||||
|
||||
public double Xpitch
|
||||
{
|
||||
get { return _xPitch; }
|
||||
set { SetAndNotify(ref _xPitch, value); }
|
||||
}
|
||||
|
||||
private double _yPitch;
|
||||
|
||||
public double Ypitch
|
||||
{
|
||||
get { return _yPitch; }
|
||||
set { SetAndNotify(ref _yPitch, value); }
|
||||
}
|
||||
|
||||
private int _usedNum;
|
||||
|
||||
public int UsedNum
|
||||
{
|
||||
get { return _usedNum; }
|
||||
set { SetAndNotify(ref _usedNum, value); }
|
||||
}
|
||||
|
||||
private int _sleepTime = 1000;
|
||||
public int SleepTime
|
||||
{
|
||||
get { return _sleepTime; }
|
||||
set { SetAndNotify(ref _sleepTime, value); }
|
||||
}
|
||||
|
||||
public IParameterItem Clone()
|
||||
{
|
||||
return MemberwiseClone() as NeedlePrintCalibrateParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.CameraAccuracyCalibrationView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
xmlns:mwControls="http://www.maxwell-gp.com/"
|
||||
xmlns:customControl="clr-namespace:MainShell.Resources.CustomControl"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="700">
|
||||
<UserControl.Resources>
|
||||
<Style TargetType="GroupBox" BasedOn="{StaticResource GroupStepControl}"/>
|
||||
<Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Right"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="Height" Value="35"/>
|
||||
</Style>
|
||||
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" >
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="Margin" Value="3"/>
|
||||
<Setter Property="Height" Value="35"/>
|
||||
<Setter Property="Width" Value="90"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
<Grid mwControls:ParameterAttach.DelayAcceptValue ="{Binding ParameterHelper}">
|
||||
<StackPanel>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Header="【第一步】针尖高度设置">
|
||||
<customControl:AxisMoveControl LableContent1="Z1(mm):"
|
||||
Value1="{Binding QuickNeedlePrintParameter.Z1InkHeight}"
|
||||
IsAllShow="False"
|
||||
ReadCommand="{mwControls:Action TeachZ1Pos}"
|
||||
IsReadOnly="False"
|
||||
MoveCommand="{mwControls:Action MoveToZ1Pos}"/>
|
||||
|
||||
</GroupBox>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Header="【第二步】WS避让位">
|
||||
<GroupBox.Content>
|
||||
<customControl:AxisMoveControl LableContent1="X2(mm):"
|
||||
Value1="{Binding QuickNeedlePrintParameter.AvoidancePoint.PointX}"
|
||||
LableContent2="Y2(mm):"
|
||||
Value2="{Binding QuickNeedlePrintParameter.AvoidancePoint.PointY}"
|
||||
ReadCommand="{mwControls:Action TeachWSPos}"
|
||||
MoveCommand="{mwControls:Action MoveToWsPos}"
|
||||
IsReadOnly="True"/>
|
||||
<!--<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Label VerticalAlignment="Center" Content="X2:"/>
|
||||
<mwControls:NumberBox Value="{Binding QuickNeedlePrintParameter.AvoidancePoint.PointX}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Label VerticalAlignment="Center" Content="Y2:"/>
|
||||
<mwControls:NumberBox Value="{Binding QuickNeedlePrintParameter.AvoidancePoint.PointY}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Button Margin="2,0" Click="{mwControls:Action TeachWSPos}" Content="示教"/>
|
||||
<Button Margin="2,0" Click="{mwControls:Action MoveToWsPos}" Content="移动"/>
|
||||
</StackPanel>-->
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Margin="2" Header="【第三步】墨水位置">
|
||||
<GroupBox.Content>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<customControl:AxisMoveControl LableContent1="X2(mm):"
|
||||
Value1="{Binding QuickNeedlePrintParameter.InkPos.PointX}"
|
||||
LableContent2="Y2(mm):"
|
||||
Value2="{Binding QuickNeedlePrintParameter.InkPos.PointY}"
|
||||
ReadCommand="{mwControls:Action TeachInkPos}"
|
||||
MoveCommand="{mwControls:Action MoveToInkPos}"
|
||||
IsReadOnly="True"/>
|
||||
|
||||
<Button Margin="2,0" HorizontalAlignment="Right" Click="{mwControls:Action InkSmearing}" Content="涂墨"/>
|
||||
</Grid>
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
<GroupBox Header="【第四步】快打针印参数设置">
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" HorizontalAlignment="Left" Content="打件颗数:"/>
|
||||
<mwControls:IntNumberBox Value="{Binding BondingNumber}" IsReadOnly="True" Width="75" Margin="4,0" />
|
||||
<Button IsEnabled="{Binding UiEnable}" Margin="2,0" Click="{mwControls:Action PositiveBonding}" Content="快打正向"/>
|
||||
<Button IsEnabled="{Binding UiEnable}" Margin="2,0" Click="{mwControls:Action NegativeBonding}" Content="快打反向"/>
|
||||
<Button IsEnabled="{Binding UiEnable}" Margin="2,0" Click="{mwControls:Action SlowBonding}" Content="补打"/>
|
||||
<Button Margin="2,0" Content="停止打件" Click="{mwControls:Action StopBonding}"/>
|
||||
</StackPanel>
|
||||
<Label Content="正向针印查看:" HorizontalAlignment="Left"/>
|
||||
<StackPanel IsEnabled="{Binding UiEnable}" HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanLastPositiveIndex}" Click="{mwControls:Action LastPositiveIndex}" Content="上一个"/>
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanNextPositiveIndex}" Click="{mwControls:Action NextPositiveIndex}" Content="下一个"/>
|
||||
</StackPanel>
|
||||
<Label Content="反向针印查看:" HorizontalAlignment="Left"/>
|
||||
<StackPanel IsEnabled="{Binding UiEnable}" HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanLastNegativeIndex}" Click="{mwControls:Action LastNegativeIndex}" Content="上一个"/>
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanNextNegativeIndex}" Click="{mwControls:Action NextNegativeIndex}" Content="下一个"/>
|
||||
</StackPanel>
|
||||
<Label Content="补打针印查看:" HorizontalAlignment="Left"/>
|
||||
<StackPanel IsEnabled="{Binding UiEnable}" HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanLastSlowIndex}" Click="{mwControls:Action LastSlowIndex}" Content="上一个"/>
|
||||
<Button Margin="2,0" IsEnabled="{Binding CanNextSlowIndex}" Click="{mwControls:Action NextSlowIndex}" Content="下一个"/>
|
||||
</StackPanel>
|
||||
<Button IsEnabled="{Binding UiEnable}" HorizontalAlignment="Right" Click="{mwControls:Action SaveParameter}" Margin="10,2" Content="保存"/>
|
||||
</StackPanel>
|
||||
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// CameraAccuracyCalibrationView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class CameraAccuracyCalibrationView : UserControl
|
||||
{
|
||||
public CameraAccuracyCalibrationView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.CylinderView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="CylinderCardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#F8FAFD"/>
|
||||
<Setter Property="BorderBrush" Value="#D4DCE8"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Padding" Value="14"/>
|
||||
<Setter Property="Margin" Value="0,0,0,12"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CylinderDotStyle" TargetType="Ellipse">
|
||||
<Setter Property="Width" Value="10"/>
|
||||
<Setter Property="Height" Value="10"/>
|
||||
<Setter Property="Fill" Value="#CBD5E1"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsOn}" Value="True">
|
||||
<Setter Property="Fill" Value="#22C55E"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CylinderActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="Padding" Value="12,6"/>
|
||||
<Setter Property="MinWidth" Value="90"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
CornerRadius="18"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="#EDF1F7">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Margin="12,12,12,8">
|
||||
<TextBlock Text="CYLINDER CONTROL / 气缸控制" FontSize="20" FontWeight="Bold" Foreground="#0F3B7A"/>
|
||||
<Border Background="#EFF6FF" BorderBrush="#BFDBFE" BorderThickness="1" CornerRadius="6" Padding="10" Margin="0,8,0,0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="最近操作:" Foreground="#475569" Margin="0,0,8,0"/>
|
||||
<TextBlock Text="{Binding PageState.LastActionTime, StringFormat={}{0:HH:mm:ss}}" Foreground="#0F172A" FontWeight="Bold" Margin="0,0,12,0"/>
|
||||
<TextBlock Text="{Binding PageState.LastActionMessage}" Foreground="#1D4ED8" FontWeight="SemiBold" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<ScrollViewer Grid.Row="1" Margin="12,0,12,12" VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl ItemsSource="{Binding PageState.Cylinders}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Style="{StaticResource CylinderCardStyle}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Name}" FontSize="18" FontWeight="Bold" Foreground="#0F3B7A"/>
|
||||
<TextBlock Text="{Binding Description}" Foreground="#64748B" Margin="0,4,0,0"/>
|
||||
</StackPanel>
|
||||
<Border Grid.Column="1" Background="#FEF3C7" CornerRadius="12" Padding="10,4" VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding ControlTypeText}" Foreground="#92400E" FontWeight="Bold"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Margin="0,12,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Margin="0,0,16,0">
|
||||
<TextBlock Text="控制" Foreground="#1D4ED8" FontWeight="Bold" Margin="0,0,0,8"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="伸出"
|
||||
Command="{Binding ExtendCommand}"
|
||||
Background="#2563EB"
|
||||
BorderBrush="#2563EB"
|
||||
Style="{StaticResource CylinderActionButtonStyle}"/>
|
||||
<Button Content="缩回"
|
||||
Command="{Binding RetractCommand}"
|
||||
Background="#F97316"
|
||||
BorderBrush="#F97316"
|
||||
Style="{StaticResource CylinderActionButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1" Margin="0,0,16,0">
|
||||
<TextBlock Text="输出信号" Foreground="#C2410C" FontWeight="Bold" Margin="0,0,0,8"/>
|
||||
<ItemsControl ItemsSource="{Binding OutputSignals}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Background="#FFF7ED" BorderBrush="#FED7AA" BorderThickness="1" CornerRadius="4" Padding="8,6" Margin="0,0,0,6">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse Style="{StaticResource CylinderDotStyle}" VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="{Binding Name}" Foreground="#9A3412" FontWeight="SemiBold"/>
|
||||
<TextBlock Text="{Binding IoNameText}" Foreground="#7C2D12" FontSize="11" TextWrapping="Wrap"/>
|
||||
<TextBlock Text="{Binding LineNo, StringFormat=线标:{0}}" Foreground="#C2410C" FontSize="11"/>
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2" Text="{Binding StateText}" Foreground="#C2410C" FontWeight="Bold"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="2">
|
||||
<TextBlock Text="反馈信号" Foreground="#166534" FontWeight="Bold" Margin="0,0,0,8"/>
|
||||
<ItemsControl ItemsSource="{Binding FeedbackSignals}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Background="#F0FDF4" BorderBrush="#BBF7D0" BorderThickness="1" CornerRadius="4" Padding="8,6" Margin="0,0,0,6">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse Style="{StaticResource CylinderDotStyle}" VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="{Binding Name}" Foreground="#166534" FontWeight="SemiBold"/>
|
||||
<TextBlock Text="{Binding IoNameText}" Foreground="#15803D" FontSize="11" TextWrapping="Wrap"/>
|
||||
<TextBlock Text="{Binding LineNo, StringFormat=线标:{0}}" Foreground="#15803D" FontSize="11"/>
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2" Text="{Binding StateText}" Foreground="#166534" FontWeight="Bold"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// CylinderView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class CylinderView : UserControl
|
||||
{
|
||||
public CylinderView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.DeviceIoView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="900">
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="IoCardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#F8FAFD"/>
|
||||
<Setter Property="BorderBrush" Value="#D4DCE8"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Margin" Value="0,0,0,12"/>
|
||||
<Setter Property="Padding" Value="14"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="StatusBadgeBorderStyle" TargetType="Border">
|
||||
<Setter Property="CornerRadius" Value="12"/>
|
||||
<Setter Property="Padding" Value="10,4"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
<Setter Property="Background" Value="#E2E8F0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="InputStatusDotStyle" TargetType="Ellipse">
|
||||
<Setter Property="Width" Value="10"/>
|
||||
<Setter Property="Height" Value="10"/>
|
||||
<Setter Property="Fill" Value="#93C5FD"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsOn}" Value="True">
|
||||
<Setter Property="Fill" Value="#2563EB"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="OutputStatusDotStyle" TargetType="Ellipse">
|
||||
<Setter Property="Width" Value="10"/>
|
||||
<Setter Property="Height" Value="10"/>
|
||||
<Setter Property="Fill" Value="#FCD34D"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsOn}" Value="True">
|
||||
<Setter Property="Fill" Value="#F97316"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="InputItemBorderStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#EFF6FF"/>
|
||||
<Setter Property="BorderBrush" Value="#DBEAFE"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1"/>
|
||||
<Setter Property="Padding" Value="8,6"/>
|
||||
<Setter Property="Margin" Value="0,0,0,4"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="OutputItemBorderStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#FFF7ED"/>
|
||||
<Setter Property="BorderBrush" Value="#FED7AA"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1"/>
|
||||
<Setter Property="Padding" Value="8,6"/>
|
||||
<Setter Property="Margin" Value="0,0,0,4"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="IoSectionBorderStyle" TargetType="Border">
|
||||
<Setter Property="CornerRadius" Value="6"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Padding" Value="10"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="IoOutputToggleButtonStyle" TargetType="ToggleButton">
|
||||
<Setter Property="Width" Value="90"/>
|
||||
<Setter Property="Height" Value="30"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Border x:Name="Root" Background="#CBD5E1" BorderBrush="#94A3B8" BorderThickness="1" CornerRadius="15">
|
||||
<Grid Margin="2">
|
||||
<Border x:Name="Knob" Width="24" Height="24" Background="White" CornerRadius="12" HorizontalAlignment="Left"/>
|
||||
<TextBlock x:Name="ToggleLabel" Text="OFF" Foreground="#334155" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,0,10,0"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="Root" Property="Background" Value="#16A34A"/>
|
||||
<Setter TargetName="Root" Property="BorderBrush" Value="#16A34A"/>
|
||||
<Setter TargetName="Knob" Property="HorizontalAlignment" Value="Right"/>
|
||||
<Setter TargetName="ToggleLabel" Property="Text" Value="ON"/>
|
||||
<Setter TargetName="ToggleLabel" Property="Foreground" Value="White"/>
|
||||
<Setter TargetName="ToggleLabel" Property="HorizontalAlignment" Value="Left"/>
|
||||
<Setter TargetName="ToggleLabel" Property="Margin" Value="10,0,0,0"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter TargetName="Root" Property="Opacity" Value="0.45"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="#EDF1F7">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Margin="10,10,10,8">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="DEVICE IO MONITOR / 设备IO监控" FontSize="20" FontWeight="Bold" Foreground="#0F3B7A"/>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Border Style="{StaticResource StatusBadgeBorderStyle}">
|
||||
<TextBlock Text="{Binding PageState.LastRefreshTime, StringFormat=刷新:{0:HH:mm:ss}}" Foreground="#475569"/>
|
||||
</Border>
|
||||
<Border>
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource StatusBadgeBorderStyle}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding PageState.IsOnline}" Value="True">
|
||||
<Setter Property="Background" Value="#DCFCE7"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding PageState.IsOnline}" Value="False">
|
||||
<Setter Property="Background" Value="#FEE2E2"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="{Binding PageState.OnlineText}">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="#B91C1C"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding PageState.IsOnline}" Value="True">
|
||||
<Setter Property="Foreground" Value="#166534"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<Border Margin="0,8,0,0" Padding="12,6">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource StatusBadgeBorderStyle}">
|
||||
<Setter Property="Background" Value="#EFF6FF"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding PageState.IsWriteSuccess}" Value="True">
|
||||
<Setter Property="Background" Value="#DCFCE7"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding PageState.IsWriteSuccess}" Value="False">
|
||||
<Setter Property="Background" Value="#FEF3C7"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding PageState.LastWriteTime, StringFormat=写入时间:{0:HH:mm:ss}}" Foreground="#475569" Margin="0,0,14,0"/>
|
||||
<TextBlock Text="{Binding PageState.LastWriteMessage}" FontWeight="SemiBold" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<ScrollViewer Grid.Row="1" Margin="10,0,10,10" VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl ItemsSource="{Binding PageState.Modules}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Style="{StaticResource IoCardStyle}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Text="{Binding Name}" FontSize="18" FontWeight="Bold" Foreground="#0F3B7A"/>
|
||||
|
||||
<Grid Grid.Row="1" Margin="0,10,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition>
|
||||
<ColumnDefinition.Style>
|
||||
<Style TargetType="ColumnDefinition">
|
||||
<Setter Property="Width" Value="*"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasInputs}" Value="False">
|
||||
<Setter Property="Width" Value="0"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ColumnDefinition.Style>
|
||||
</ColumnDefinition>
|
||||
<ColumnDefinition>
|
||||
<ColumnDefinition.Style>
|
||||
<Style TargetType="ColumnDefinition">
|
||||
<Setter Property="Width" Value="*"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasOutputs}" Value="False">
|
||||
<Setter Property="Width" Value="0"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ColumnDefinition.Style>
|
||||
</ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border BorderBrush="#BFDBFE" Background="#F8FBFF">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource IoSectionBorderStyle}">
|
||||
<Setter Property="Margin" Value="0,0,6,0"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasInputs}" Value="False">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding HasOutputs}" Value="False">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel>
|
||||
<TextBlock Text="输入 IO" Foreground="#1D4ED8" FontWeight="Bold" Margin="0,0,0,8"/>
|
||||
<ItemsControl ItemsSource="{Binding InputPoints}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Style="{StaticResource InputItemBorderStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse Style="{StaticResource InputStatusDotStyle}" VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="{Binding Description}" Foreground="#1E3A8A" FontWeight="SemiBold"/>
|
||||
<TextBlock Text="{Binding StationNo, StringFormat=站号:{0}}" Foreground="#1D4ED8" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LineNo, StringFormat=线标:{0}}" Foreground="#1D4ED8" FontSize="11"/>
|
||||
<TextBlock Text="{Binding Name}" Foreground="#64748B" FontSize="11" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2" Text="{Binding StateText}" VerticalAlignment="Center" Foreground="#1E40AF" FontWeight="Bold"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="1" BorderBrush="#FDBA74" Background="#FFF9F2">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource IoSectionBorderStyle}">
|
||||
<Setter Property="Margin" Value="6,0,0,0"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasOutputs}" Value="False">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding HasInputs}" Value="False">
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel>
|
||||
<TextBlock Text="输出 IO" Foreground="#C2410C" FontWeight="Bold" Margin="0,0,0,8"/>
|
||||
<ItemsControl ItemsSource="{Binding OutputPoints}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Style="{StaticResource OutputItemBorderStyle}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse Style="{StaticResource OutputStatusDotStyle}" VerticalAlignment="Center" Margin="0,0,8,0"/>
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="{Binding Description}" Foreground="#9A3412" FontWeight="SemiBold"/>
|
||||
<TextBlock Text="{Binding StationNo, StringFormat=站号:{0}}" Foreground="#C2410C" FontSize="11"/>
|
||||
<TextBlock Text="{Binding LineNo, StringFormat=线标:{0}}" Foreground="#C2410C" FontSize="11"/>
|
||||
<TextBlock Text="{Binding Name}" Foreground="#7C2D12" FontSize="11" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2" Text="{Binding StateText}" Margin="0,0,10,0" VerticalAlignment="Center" Foreground="#C2410C" FontWeight="Bold"/>
|
||||
<ToggleButton Grid.Column="3"
|
||||
Style="{StaticResource IoOutputToggleButtonStyle}"
|
||||
IsChecked="{Binding IsOn, Mode=OneWay}"
|
||||
Command="{Binding ToggleCommand}"
|
||||
IsEnabled="{Binding CanWrite}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
public partial class DeviceIoView : UserControl
|
||||
{
|
||||
public DeviceIoView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.DeviceMaintanceView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
xmlns:mw="http://www.maxwell-gp.com/"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Margin="-40,0,0,0" Grid.Column="0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<mw:SideMenu ItemsSource="{Binding MenuItemWraps}"
|
||||
SelectedItem="{Binding SelectedMenuItem, Mode=TwoWay}"
|
||||
Grid.Row ="0" Width="180"
|
||||
ExpandMode="Accordion"
|
||||
AutoSelect="True"
|
||||
>
|
||||
<mw:SideMenu.ItemContainerStyle>
|
||||
<Style TargetType="{x:Type mw:SideMenuItem}" BasedOn="{StaticResource SideMenuItemHeaderAccordionBaseStyle}">
|
||||
<Setter Property="Header" Value="{Binding Header}" />
|
||||
<Setter Property="Tag" Value="{Binding Tag}" />
|
||||
</Style>
|
||||
</mw:SideMenu.ItemContainerStyle>
|
||||
</mw:SideMenu>
|
||||
|
||||
</Grid>
|
||||
|
||||
<ContentControl Margin="5,0" Grid.Column="1" mw:View.Model="{Binding CurrentScreen}"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// DeviceMaintanceView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class DeviceMaintanceView : UserControl
|
||||
{
|
||||
public DeviceMaintanceView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.HardwareTestView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mw="http://www.maxwell-gp.com/"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<Style x:Key="HardwareTestLabelStyle" TargetType="Label" BasedOn="{StaticResource ProcessLabelStyle}">
|
||||
<Setter Property="Width" Value="126"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="HardwareTestValueBorderStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#F8FAFC"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource ProcessCardBorderBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
<Setter Property="Padding" Value="12,6"/>
|
||||
<Setter Property="Margin" Value="8,0,18,0"/>
|
||||
<Setter Property="MinWidth" Value="150"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="HardwareTestValueTextStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource ProcessBodyForegroundBrush}"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="HardwareTestIntNumberBoxStyle" TargetType="{x:Type mw:IntNumberBox}" BasedOn="{StaticResource ProcessLargeIntNumberBoxStyle}">
|
||||
<Setter Property="Margin" Value="8,0,18,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="HardwareTestButtonStyle" TargetType="Button" BasedOn="{StaticResource TestButtonStyle}">
|
||||
<Setter Property="Width" Value="110"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Margin" Value="8,0,0,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="HardwareTestStartButtonStyle" TargetType="Button" BasedOn="{StaticResource StartButtonStyle}">
|
||||
<Setter Property="Width" Value="110"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Margin" Value="8,0,0,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="HardwareTestStopButtonStyle" TargetType="Button" BasedOn="{StaticResource CloseButtonStyle}">
|
||||
<Setter Property="Width" Value="110"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Margin" Value="8,0,0,0"/>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="{StaticResource ProcessPageBackgroundBrush}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="4" Padding="0,0,4,0">
|
||||
<StackPanel Margin="0,0,0,4">
|
||||
<GroupBox Header="{DynamicResource Diastimeter}" Style="{StaticResource ProcessWideCardGroupBoxStyle}">
|
||||
<WrapPanel>
|
||||
<Label Style="{StaticResource HardwareTestLabelStyle}" Content="{DynamicResource DiastimeterValue}"/>
|
||||
<Border Style="{StaticResource HardwareTestValueBorderStyle}">
|
||||
<TextBlock Style="{StaticResource HardwareTestValueTextStyle}" Text="{Binding Message}"/>
|
||||
</Border>
|
||||
<Button Style="{StaticResource HardwareTestButtonStyle}" Click="{mw:Action btnZeroClick}" Content="{DynamicResource SetZero}"/>
|
||||
<Button Style="{StaticResource HardwareTestButtonStyle}" Click="{mw:Action btnGetCurrentValueClick}" Content="{DynamicResource GetCurrentValue}"/>
|
||||
</WrapPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="FFU" Style="{StaticResource ProcessWideCardGroupBoxStyle}">
|
||||
<WrapPanel>
|
||||
<Label Style="{StaticResource HardwareTestLabelStyle}" Content="{DynamicResource FFURotateSpeed}"/>
|
||||
<mw:IntNumberBox Style="{StaticResource HardwareTestIntNumberBoxStyle}" Value="{Binding FFURotateSpeed}" ValueChanged="{mw:Action FFURotateSpeedChanged}"/>
|
||||
<Button Style="{StaticResource HardwareTestStartButtonStyle}" Content="{DynamicResource Open}" Click="{mw:Action BtnOpenFFU}"/>
|
||||
<Button Style="{StaticResource HardwareTestStopButtonStyle}" Content="{DynamicResource Close}" Click="{mw:Action BtnCloseFFU}"/>
|
||||
</WrapPanel>
|
||||
</GroupBox>
|
||||
|
||||
<WrapPanel>
|
||||
<GroupBox Header="{DynamicResource WaferScaner}" Style="{StaticResource ProcessCardGroupBoxStyle}" Width="430" Margin="0,0,18,18">
|
||||
<WrapPanel>
|
||||
<Button Style="{StaticResource HardwareTestButtonStyle}" Click="{mw:Action btnScanWaferBarcodeClick}" Content="{DynamicResource GetCurrentValue}"/>
|
||||
<Border Style="{StaticResource HardwareTestValueBorderStyle}" MinWidth="180" Margin="8,0,0,0">
|
||||
<TextBlock Style="{StaticResource HardwareTestValueTextStyle}" Text="{Binding WaferBarcode}"/>
|
||||
</Border>
|
||||
</WrapPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="{DynamicResource GlassScaner}" Style="{StaticResource ProcessCardGroupBoxStyle}" Width="430" Margin="0,0,0,18">
|
||||
<WrapPanel>
|
||||
<Button Style="{StaticResource HardwareTestButtonStyle}" Click="{mw:Action btnScanGlassBarcodeClick}" Content="{DynamicResource GetCurrentValue}"/>
|
||||
<Border Style="{StaticResource HardwareTestValueBorderStyle}" MinWidth="180" Margin="8,0,0,0">
|
||||
<TextBlock Style="{StaticResource HardwareTestValueTextStyle}" Text="{Binding GlassBarcode}"/>
|
||||
</Border>
|
||||
</WrapPanel>
|
||||
</GroupBox>
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// HardwareTestView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class HardwareTestView : UserControl
|
||||
{
|
||||
public HardwareTestView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.IOMaintanceView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
xmlns:mw="http://www.maxwell-gp.com/"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Border Background="{StaticResource BackgroundBrush}" BorderBrush="{StaticResource BorderBrush}" BorderThickness="2,2,2,2">
|
||||
<TabControl mw:TabControlAttach.FontSize="14">
|
||||
<TabItem Header="IO监控" >
|
||||
<ContentControl mw:View.Model="{Binding IOMonitorViewModel}" Margin="15"/>
|
||||
</TabItem>
|
||||
<TabItem Header="气缸控制" >
|
||||
<ContentControl mw:View.Model="{Binding CylinderViewModel}" Margin="15"/>
|
||||
</TabItem>
|
||||
<TabItem Header="IO测试" >
|
||||
<ContentControl mw:View.Model="{Binding IoTestViewModel}" Margin="15"/>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.IOMonitorView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
xmlns:mw="http://www.maxwell-gp.com/"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<ContentControl mw:View.Model="{Binding DeviceIoViewModel}"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// IOMonitorView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class IOMonitorView : UserControl
|
||||
{
|
||||
public IOMonitorView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.IoTestView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mw="http://www.maxwell-gp.com/"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="560" d:DesignWidth="980">
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="IoTestGroupBoxStyle" TargetType="GroupBox" BasedOn="{StaticResource ProcessWideCardGroupBoxStyle}">
|
||||
<Setter Property="Margin" Value="0,0,0,16"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="IoTestLabelStyle" TargetType="Label" BasedOn="{StaticResource ProcessLabelStyle}">
|
||||
<Setter Property="Width" Value="95"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="IoTestNumberBoxStyle" TargetType="{x:Type mw:IntNumberBox}" BasedOn="{StaticResource ProcessLargeIntNumberBoxStyle}">
|
||||
<Setter Property="Width" Value="110"/>
|
||||
<Setter Property="Margin" Value="0,0,12,8"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="IoTestButtonStyle" TargetType="Button" BasedOn="{StaticResource TestButtonStyle}">
|
||||
<Setter Property="Width" Value="100"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Margin" Value="0,0,12,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="IoTestResultBorderStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#F8FAFC"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource ProcessCardBorderBrush}"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="CornerRadius" Value="4"/>
|
||||
<Setter Property="Padding" Value="12,8"/>
|
||||
<Setter Property="Margin" Value="0,4,0,0"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="IoTestCheckBoxStyle" TargetType="CheckBox">
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Margin" Value="0,0,18,8"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid Background="{StaticResource ProcessPageBackgroundBrush}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="4" Padding="0,0,4,0">
|
||||
<StackPanel Margin="0,0,0,4">
|
||||
<GroupBox Header="Delta IO状态" Style="{StaticResource IoTestGroupBoxStyle}">
|
||||
<StackPanel>
|
||||
<WrapPanel>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="控制卡状态"/>
|
||||
<TextBlock VerticalAlignment="Center" Text="{Binding CardStatusText}" TextWrapping="Wrap" Width="620"/>
|
||||
<Button Style="{StaticResource IoTestButtonStyle}" Content="刷新状态" Click="{mw:Action RefreshCardStatus}"/>
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="数字量 Bit 测试" Style="{StaticResource IoTestGroupBoxStyle}">
|
||||
<StackPanel>
|
||||
<WrapPanel>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="CardNo"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding BitState.CardNo}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="Node"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding BitState.Node}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="Slot"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding BitState.Slot}"/>
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="Index"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding BitState.Index}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="SubIndex"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding BitState.SubIndex}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="BitNo"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding BitState.BitNo}"/>
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="IoType"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding BitState.IoType}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="ReadIoType"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding BitState.ReadIoType}"/>
|
||||
<CheckBox Style="{StaticResource IoTestCheckBoxStyle}" Content="写入值" IsChecked="{Binding BitState.WriteValue}"/>
|
||||
<CheckBox Style="{StaticResource IoTestCheckBoxStyle}" Content="读取结果" IsChecked="{Binding BitState.ReadValue}" IsEnabled="False"/>
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel Margin="0,4,0,0">
|
||||
<Button Style="{StaticResource IoTestButtonStyle}" Content="读取 Bit" Click="{mw:Action ReadBit}"/>
|
||||
<Button Style="{StaticResource IoTestButtonStyle}" Content="写入 Bit" Click="{mw:Action WriteBit}"/>
|
||||
<TextBlock VerticalAlignment="Center" Text="{Binding BitState.ReturnCode, StringFormat=返回码:{0}}"/>
|
||||
</WrapPanel>
|
||||
|
||||
<Border Style="{StaticResource IoTestResultBorderStyle}">
|
||||
<TextBlock Text="{Binding BitState.ResultMessage}" TextWrapping="Wrap"/>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="模拟量 DA 测试" Style="{StaticResource IoTestGroupBoxStyle}">
|
||||
<StackPanel>
|
||||
<WrapPanel>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="CardNo"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding DaState.CardNo}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="Node"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding DaState.Node}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="Slot"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding DaState.Slot}"/>
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="Index"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding DaState.Index}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="SubIndex"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding DaState.SubIndex}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="ByteSize"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding DaState.ByteSize}"/>
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="IoType"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding DaState.IoType}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="写入值"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding DaState.WriteRawValue}"/>
|
||||
<Label Style="{StaticResource IoTestLabelStyle}" Content="读取值"/>
|
||||
<mw:IntNumberBox Style="{StaticResource IoTestNumberBoxStyle}" Value="{Binding DaState.ReadRawValue}" IsEnabled="False"/>
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel>
|
||||
<CheckBox Style="{StaticResource IoTestCheckBoxStyle}" Content="有符号" IsChecked="{Binding DaState.Signed}"/>
|
||||
<Button Style="{StaticResource IoTestButtonStyle}" Content="读取 DA" Click="{mw:Action ReadDa}"/>
|
||||
<Button Style="{StaticResource IoTestButtonStyle}" Content="写入 DA" Click="{mw:Action WriteDa}"/>
|
||||
<TextBlock VerticalAlignment="Center" Text="{Binding DaState.ReturnCode, StringFormat=返回码:{0}}"/>
|
||||
</WrapPanel>
|
||||
|
||||
<Border Style="{StaticResource IoTestResultBorderStyle}">
|
||||
<TextBlock Text="{Binding DaState.ResultMessage}" TextWrapping="Wrap"/>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// IoTestView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class IoTestView : UserControl
|
||||
{
|
||||
public IoTestView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.LaserCompensationView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mw="http://www.maxwell-gp.com/"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="560"
|
||||
d:DesignWidth="900">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Right"/>
|
||||
<Setter Property="Margin" Value="8,0,8,0"/>
|
||||
<Setter Property="Foreground" Value="{StaticResource ProcessBodyForegroundBrush}"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
|
||||
<Setter Property="Foreground" Value="{StaticResource ProcessBodyForegroundBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
|
||||
<Setter Property="Width" Value="110"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Margin" Value="8,0,0,0"/>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
||||
<Grid Background="{StaticResource ProcessPageBackgroundBrush}" Margin="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<GroupBox Grid.Row="0" Header="{DynamicResource LaserCompensationParameters}" Style="{StaticResource ProcessWideCardGroupBoxStyle}">
|
||||
<Grid Margin="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="280"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="280"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="280"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="{DynamicResource AxisName}"/>
|
||||
<ComboBox Grid.Row="0" Grid.Column="1"
|
||||
Style="{StaticResource ProcessLargeComboBoxStyle}"
|
||||
|
||||
ItemsSource="{Binding AxisNames}"
|
||||
SelectedItem="{Binding SelectedAxisName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="2" Content="{DynamicResource LaserCompensationStartPosition}"/>
|
||||
<mw:NumberBox Grid.Row="0" Grid.Column="3"
|
||||
Style="{StaticResource ProcessLargeNumberBoxStyle}"
|
||||
|
||||
Value="{Binding Setting.StartPos, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
DecimalPlaces="4"
|
||||
mw:NumericKeypadAttach.IsEnabled="True"
|
||||
ShowUpDownButton="True"/>
|
||||
|
||||
<Label Grid.Row="0" Grid.Column="4" Content="{DynamicResource LaserCompensationStepDistance}"/>
|
||||
<mw:NumberBox Grid.Row="0" Grid.Column="5"
|
||||
Style="{StaticResource ProcessLargeNumberBoxStyle}"
|
||||
|
||||
Value="{Binding Setting.Steps, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
DecimalPlaces="4"
|
||||
mw:NumericKeypadAttach.IsEnabled="True"
|
||||
ShowUpDownButton="True"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="{DynamicResource LaserCompensationStepCount}"/>
|
||||
<mw:IntNumberBox Grid.Row="1" Grid.Column="1"
|
||||
Style="{StaticResource ProcessLargeIntNumberBoxStyle}"
|
||||
|
||||
Value="{Binding Setting.StepsCount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
mw:NumericKeypadAttach.IsEnabled="True"
|
||||
ShowUpDownButton="True"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="2" Content="{DynamicResource LaserCompensationJumpPosition}"/>
|
||||
<mw:NumberBox Grid.Row="1" Grid.Column="3"
|
||||
Style="{StaticResource ProcessLargeNumberBoxStyle}"
|
||||
|
||||
Value="{Binding Setting.JumpPos, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
DecimalPlaces="4"
|
||||
mw:NumericKeypadAttach.IsEnabled="True"
|
||||
ShowUpDownButton="True"/>
|
||||
|
||||
<Label Grid.Row="1" Grid.Column="4" Content="{DynamicResource LaserCompensationCycleCount}"/>
|
||||
<mw:IntNumberBox Grid.Row="1" Grid.Column="5"
|
||||
Style="{StaticResource ProcessLargeIntNumberBoxStyle}"
|
||||
|
||||
Value="{Binding Setting.WorkCount, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
mw:NumericKeypadAttach.IsEnabled="True"
|
||||
ShowUpDownButton="True"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="{DynamicResource Speed}"/>
|
||||
<mw:NumberBox Grid.Row="2" Grid.Column="1"
|
||||
Style="{StaticResource ProcessLargeNumberBoxStyle}"
|
||||
|
||||
Value="{Binding Setting.Speed, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
DecimalPlaces="4"
|
||||
mw:NumericKeypadAttach.IsEnabled="True"
|
||||
ShowUpDownButton="True"/>
|
||||
|
||||
<Label Grid.Row="2" Grid.Column="2" Content="{DynamicResource LaserCompensationDelaySeconds}"/>
|
||||
<mw:NumberBox Grid.Row="2" Grid.Column="3"
|
||||
Style="{StaticResource ProcessLargeNumberBoxStyle}"
|
||||
|
||||
Value="{Binding Setting.DwellTime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
DecimalPlaces="3"
|
||||
mw:NumericKeypadAttach.IsEnabled="True"
|
||||
ShowUpDownButton="True"/>
|
||||
|
||||
<Button Grid.Row="2" Grid.Column="5" Content="{DynamicResource Save}" Click="{mw:Action Save}" HorizontalAlignment="Left"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Grid.Row="1" Header="{DynamicResource LaserCompensationExecutionControl}" Style="{StaticResource ProcessWideCardGroupBoxStyle}" Margin="0,12,0,0">
|
||||
<Grid Margin="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Content="{DynamicResource Start}" IsEnabled="{Binding UiEnable}" Click="{mw:Action StartAsync}"/>
|
||||
<Button Grid.Column="1" Content="{DynamicResource Stop}" IsEnabled="{Binding IsRunning}" Click="{mw:Action Stop}"/>
|
||||
|
||||
<TextBlock Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Text="{DynamicResource LaserCompensationTrajectoryOrder}"
|
||||
Margin="18,0,0,0"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Grid.Row="2" Header="{DynamicResource LaserCompensationExecutionStatus}" Style="{StaticResource ProcessWideCardGroupBoxStyle}" Margin="0,12,0,0">
|
||||
<Grid Margin="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="120"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="120"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="160"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Grid.Column="0" Content="{DynamicResource LaserCompensationCurrentCycle}"/>
|
||||
<TextBlock Grid.Column="1" VerticalAlignment="Center" Text="{Binding CurrentLoopIndex}"/>
|
||||
<Label Grid.Column="2" Content="{DynamicResource LaserCompensationCurrentPoint}"/>
|
||||
<TextBlock Grid.Column="3" VerticalAlignment="Center" Text="{Binding CurrentPointIndex}"/>
|
||||
<Label Grid.Column="4" Content="{DynamicResource LaserCompensationCurrentTarget}"/>
|
||||
<TextBlock Grid.Column="5" VerticalAlignment="Center" Text="{Binding CurrentTargetPosition, StringFormat=F4}"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Grid.Row="3" Header="{DynamicResource Description}" Style="{StaticResource ProcessWideCardGroupBoxStyle}" Margin="0,12,0,0">
|
||||
<StackPanel Margin="4">
|
||||
<TextBlock TextWrapping="Wrap"
|
||||
Text="{DynamicResource LaserCompensationDescriptionPrimary}"/>
|
||||
<TextBlock Margin="0,8,0,0"
|
||||
TextWrapping="Wrap"
|
||||
Text="{DynamicResource LaserCompensationDescriptionSecondary}"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
public partial class LaserCompensationView : UserControl
|
||||
{
|
||||
public LaserCompensationView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.NeedleBaseView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
xmlns:mw="http://www.maxwell-gp.com/"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox Grid.Row="0" Background="#D7DDE4"
|
||||
Style="{StaticResource NavigationListBoxStyle}"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ItemsSource="{Binding NavigationItems}"
|
||||
SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate >
|
||||
<StackPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}"
|
||||
FontWeight="Bold"
|
||||
Foreground="#505050"
|
||||
FontSize="14" />
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentControl Margin="2" Content="{Binding CameraAxisViewModel}"/>
|
||||
<Border BorderBrush="Gray" BorderThickness="1" Margin="5,2" Grid.Column="1">
|
||||
<ContentControl Margin="2"
|
||||
mw:View.Model="{Binding CurrentScreen}"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// NeedleBaseView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class NeedleBaseView : UserControl
|
||||
{
|
||||
public NeedleBaseView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.NeedleCaliView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
xmlns:mwControls="http://www.maxwell-gp.com/"
|
||||
xmlns:Att="clr-namespace:MainShell.Common.ControlAttribute"
|
||||
xmlns:customControl="clr-namespace:MainShell.Resources.CustomControl"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="850" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<Style TargetType="GroupBox" BasedOn="{StaticResource GroupStepControl}"/>
|
||||
<Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Right"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="Height" Value="35"/>
|
||||
<Setter Property="Width" Value="80"/>
|
||||
</Style>
|
||||
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="Margin" Value="3"/>
|
||||
<Setter Property="Height" Value="35"/>
|
||||
<Setter Property="Width" Value="90"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
<Grid mwControls:ParameterAttach.DelayAcceptValue="{Binding ParameterHelper}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Visible" Margin="5" ClipToBounds="True">
|
||||
<StackPanel>
|
||||
<GroupBox Header="【第一步】对刀仪偏差设置" IsEnabled="{Binding UiEnable}">
|
||||
<StackPanel Margin="5" HorizontalAlignment="Center" Orientation="Horizontal">
|
||||
<Label Content="对刀时偏差:" />
|
||||
<mwControls:NumberBox Value="{Binding NeedleZCalibrationItem.KnifeOffset}" mwControls:NumericKeypadAttach.IsEnabled="True" Minimum="-1000" Maximum="1000" HorizontalAlignment="Left" Margin="2" Width="80" Height="35" />
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
<GroupBox Header="【第二步】SZ / StagePlatform设置" IsEnabled="{Binding UiEnable}">
|
||||
<customControl:AxisMoveControl LableContent1="SZ(mm):"
|
||||
Value1="{Binding NeedleZCalibrationItem.CZHeight}"
|
||||
LableContent2="StagePlatform高度:"
|
||||
Value2="{Binding NeedleZCalibrationItem.StageHeight}"
|
||||
IsAllShow="{Binding HasStagePlatform}"
|
||||
MoveCommand="{mwControls:Action MoveCzCurrentLocation}"/>
|
||||
</GroupBox>
|
||||
<GroupBox Header="【第三步】龙门2的避让位置" IsEnabled="{Binding UiEnable}">
|
||||
<customControl:AxisMoveControl LableContent1="X2(mm):"
|
||||
Value1="{Binding NeedleZCalibrationItem.Gantry2AvoidPositionX}"
|
||||
LableContent2="Y2(mm):"
|
||||
Value2="{Binding NeedleZCalibrationItem.Gantry2AvoidPositionY}"
|
||||
ReadCommand="{mwControls:Action ReadGantry2CurrentLocation}"
|
||||
MoveCommand="{mwControls:Action MoveGantry2ToCurrentLocation}"/>
|
||||
</GroupBox>
|
||||
<GroupBox Header="【第四步】针尖对准对刀仪位置" IsEnabled="{Binding UiEnable}">
|
||||
<customControl:AxisMoveControl LableContent1="X1(mm):"
|
||||
Value1="{Binding NeedleZCalibrationItem.SupportPinPositionX}"
|
||||
LableContent2="Y1(mm):"
|
||||
Value2="{Binding NeedleZCalibrationItem.SupportPinPositionY}"
|
||||
ReadCommand="{mwControls:Action ReadSupportPinCurrentLocation}"
|
||||
MoveCommand="{mwControls:Action MoveSupportPinToCurrentLocation}"/>
|
||||
</GroupBox>
|
||||
<GroupBox Header="【第五步】Z1设置" IsEnabled="{Binding UiEnable}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="2*"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<UniformGrid Columns="4" Rows="1">
|
||||
<Label Content="开始位置(mm)" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" />
|
||||
<mwControls:NumberBox Value="{Binding NeedleZCalibrationItem.Z1StartPosition}" mwControls:NumericKeypadAttach.IsEnabled="True" Minimum="-1000" Maximum="1000" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Margin="2" Width="80" Height="35" />
|
||||
<Label Content="速度(mm/s)" Grid.Row="0" Grid.Column="2" HorizontalAlignment="Right" />
|
||||
<mwControls:NumberBox Value="{Binding NeedleZCalibrationItem.Z1Speed}" mwControls:NumericKeypadAttach.IsEnabled="True" Minimum="-1000" Maximum="1000" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Left" Margin="2" Width="80" Height="35" />
|
||||
</UniformGrid>
|
||||
<UniformGrid Columns="2" Rows="1" Grid.Column="1">
|
||||
<Label Content="下降距离(mm)" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right" />
|
||||
<mwControls:NumberBox Value="{Binding NeedleZCalibrationItem.Z1DropMaxPosition}" mwControls:NumericKeypadAttach.IsEnabled="True" Minimum="-1000" Maximum="1000" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Margin="2" Width="80" Height="35" />
|
||||
</UniformGrid>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<GroupBox Header="【第六步】刺针触碰到对刀仪" IsEnabled="{Binding UiEnable}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="100"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Visibility="Visible" Content="基准值(mm):" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" />
|
||||
<mwControls:NumberBox Visibility="Visible" IsReadOnly="True" Value="{Binding NeedleZCalibrationItem.NeedleTouchHeightBase}" mwControls:NumericKeypadAttach.IsEnabled="True" Minimum="-1000" Maximum="1000" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Margin="5" Width="80" Height="35" />
|
||||
|
||||
<Label Content="Z1平均高度(mm):" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right" />
|
||||
<mwControls:NumberBox IsReadOnly="True" Value="{Binding NeedleZCalibrationItem.NeedleTouchHeightAve}" mwControls:NumericKeypadAttach.IsEnabled="True" Minimum="-1000" Maximum="1000" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Margin="5" Width="80" Height="35" />
|
||||
|
||||
<Label Content="对刀次数:" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right" />
|
||||
<mwControls:NumberBox Value="{Binding NeedleZCalibrationItem.NeedleTouchCount}" mwControls:NumericKeypadAttach.IsEnabled="True" Minimum="1" Maximum="100" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Left" Margin="5" Width="80" Height="35" />
|
||||
|
||||
<Label Content="当前使用对刀高度(mm):" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Right" Width="140"/>
|
||||
<mwControls:NumberBox IsEnabled="False" Grid.Row="3" Value="{Binding NeedleZCalibrationItem.CurrentNeedleTouchHeight}" mwControls:NumericKeypadAttach.IsEnabled="True" Minimum="-1000" Maximum="1000" Grid.Column="1" HorizontalAlignment="Left" Margin="5" Width="80" Height="35" />
|
||||
|
||||
<Label Content="对刀与基准偏差(mm):" Grid.Row="4" Grid.Column="0" HorizontalAlignment="Right" />
|
||||
<mwControls:NumberBox IsReadOnly="True" Grid.Row="4" Value="{Binding NeedleZCalibrationItem.NeedleTouchOffset}" mwControls:NumericKeypadAttach.IsEnabled="True" Minimum="-1000" Maximum="1000" Grid.Column="1" HorizontalAlignment="Left" Margin="5" Width="80" Height="35" />
|
||||
|
||||
<Grid Grid.Column="2" Grid.ColumnSpan="2" Grid.RowSpan="5">
|
||||
<ListView ItemsSource="{Binding NeedleZCalibrationItem.NeedleTouchRecords}" SelectedItem="{Binding SelectedRecord}">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="当前次数" DisplayMemberBinding="{Binding CurrentCount}" Width="100"/>
|
||||
<GridViewColumn Header="Z1高度(mm)" DisplayMemberBinding="{Binding Height}" Width="210"/>
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
<GroupBox Header="【第七步】对刀控制" IsEnabled="{Binding IsEnabledNeedleCalibrationControl}">
|
||||
<StackPanel>
|
||||
<StackPanel Margin="4" IsEnabled="{Binding UiEnable}" Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<CheckBox Content="自动抬高" Margin="6,0" IsChecked="{Binding AutoRaiseZ1}"/>
|
||||
<Button Visibility="Collapsed" Content="设置当前基准值" Tag="设置当前基准值" Click="{mwControls:Action SetBaseHeight}" Margin="6,0" />
|
||||
<Button Content="Z1对刀" Tag="Z1对刀" Margin="6,0" Click="{mwControls:Action StartSingleZ1CalibrationAsync}"/>
|
||||
<Button Content="使用当前对刀高度" Width="120" Tag="使用当前对刀高度" Click="{mwControls:Action UseCurrentZ1Height}" Margin="6,0" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="4" Orientation="Horizontal">
|
||||
<Button Content="开始" Tag="开始" Click="{mwControls:Action StartCalibrationAsync}" Margin="6,0" IsEnabled="{Binding UiEnable}"/>
|
||||
<Button Content="停止" Tag="停止" Click="{mwControls:Action StopCalibrationAsync}" Margin="6,0" IsEnabled="{Binding UiEnable, Converter={StaticResource boolToInversionConverter}}"/>
|
||||
<Button Content="保存" Tag="保存" Click="{mwControls:Action SaveCalibration}" Margin="6,0" IsEnabled="{Binding UiEnable}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// NeedleCaliView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class NeedleCaliView : UserControl
|
||||
{
|
||||
public NeedleCaliView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
<UserControl x:Class="MainShell.DeviceMaintance.View.NeedleCameraPrintView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:MainShell.DeviceMaintance.View"
|
||||
xmlns:mwControls="http://www.maxwell-gp.com/"
|
||||
xmlns:customControl="clr-namespace:MainShell.Resources.CustomControl"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="750" d:DesignWidth="800">
|
||||
<UserControl.Resources>
|
||||
<Style TargetType="GroupBox" BasedOn="{StaticResource GroupStepControl}"/>
|
||||
<Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||
<Setter Property="Margin" Value="5"/>
|
||||
<Setter Property="Height" Value="35"/>
|
||||
<Setter Property="Width" Value="80"/>
|
||||
</Style>
|
||||
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" >
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="Margin" Value="3"/>
|
||||
<Setter Property="Height" Value="35"/>
|
||||
<Setter Property="Width" Value="90"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
<Grid mwControls:ParameterAttach.DelayAcceptValue ="{Binding ParameterHelper}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Margin="2" Header="【第一步】基础设置">
|
||||
<GroupBox.Content>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Button Click="{mwControls:Action MoveToOrginPos}" Content="SXSZ至初始位" Width="100"/>
|
||||
<GroupBox Header="速度设置" Style="{x:Null}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<RadioButton GroupName="speed" Click="{mwControls:Action SpeedChanged}" Tag="10" Margin="5,0" Content="10"/>
|
||||
<RadioButton GroupName="speed" IsChecked="True" Click="{mwControls:Action SpeedChanged}" Tag="50" Margin="5,0" Content="50"/>
|
||||
<RadioButton GroupName="speed" Click="{mwControls:Action SpeedChanged}" Tag="100" Margin="5,0" Content="100"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Margin="2" Header="【第二步】WS避让位">
|
||||
<GroupBox.Content>
|
||||
<customControl:AxisMoveControl LableContent1="X2(mm):"
|
||||
Value1="{Binding NeedlePrintCalibrateParameter.AvoidancePoint.PointX}"
|
||||
LableContent2="Y2(mm):"
|
||||
Value2="{Binding NeedlePrintCalibrateParameter.AvoidancePoint.PointY}"
|
||||
ReadCommand="{mwControls:Action TeachWSPos}"
|
||||
MoveCommand="{mwControls:Action MoveToWsPos}"/>
|
||||
<!--<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Label VerticalAlignment="Center" Content="X2:"/>
|
||||
<mwControls:NumberBox Value="{Binding NeedlePrintCalibrateParameter.AvoidancePoint.PointX}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Label VerticalAlignment="Center" Content="Y2:"/>
|
||||
<mwControls:NumberBox Value="{Binding NeedlePrintCalibrateParameter.AvoidancePoint.PointY}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Button Margin="2,0" Click="{mwControls:Action TeachWSPos}" Content="示教"/>
|
||||
<Button Margin="2,0" Click="{mwControls:Action MoveToWsPos}" Content="移动"/>
|
||||
</StackPanel>-->
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Margin="2" Header="【第三步】Z1位置设置">
|
||||
<GroupBox.Content>
|
||||
<customControl:AxisMoveControl LableContent1="Z1(mm):"
|
||||
Value1="{Binding NeedlePrintCalibrateParameter.Z1WorkHeight}"
|
||||
IsAllShow="False"
|
||||
ReadCommand="{mwControls:Action TeachZ1Pos}"
|
||||
MoveCommand="{mwControls:Action MoveToZ1Pos}"/>
|
||||
<!--<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Label VerticalAlignment="Center" Content="Z1:"/>
|
||||
<mwControls:NumberBox mwControls:NumericKeypadAttach.IsEnabled="True" Value="{Binding NeedlePrintCalibrateParameter.Z1WorkHeight, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" Width="80" Margin="4,0" />
|
||||
<Button Margin="2,0" Click="{mwControls:Action TeachZ1Pos}" Content="示教"/>
|
||||
<Button Margin="2,0" Click="{mwControls:Action MoveToZ1Pos}" Content="移动"/>
|
||||
</StackPanel>-->
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Margin="2" Header="【第四步】Z2位置设置">
|
||||
<GroupBox.Content>
|
||||
<customControl:AxisMoveControl LableContent1="Z2(mm):"
|
||||
Value1="{Binding NeedlePrintCalibrateParameter.Z2WorkHeight}"
|
||||
IsAllShow="False"
|
||||
ReadCommand="{mwControls:Action TeachZ2Pos}"
|
||||
MoveCommand="{mwControls:Action MoveToZ2Pos}"/>
|
||||
<!--<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Label VerticalAlignment="Center" Content="Z2:"/>
|
||||
<mwControls:NumberBox mwControls:NumericKeypadAttach.IsEnabled="True" Value="{Binding NeedlePrintCalibrateParameter.Z2WorkHeight, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="False" Width="80" Margin="4,0" />
|
||||
<Button Margin="2,0" Click="{mwControls:Action TeachZ2Pos}" Content="示教"/>
|
||||
<Button Margin="2,0" Click="{mwControls:Action MoveToZ2Pos}" Content="移动"/>
|
||||
</StackPanel>-->
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Margin="2" Header="【第五步】铜箔区域设置">
|
||||
<GroupBox.Content>
|
||||
<StackPanel>
|
||||
<Label Content="起点设置:"/>
|
||||
<customControl:AxisMoveControl LableContent1="X1(mm):"
|
||||
Value1="{Binding NeedlePrintCalibrateParameter.StartPoint.PointX}"
|
||||
LableContent2="Y1(mm):"
|
||||
Value2="{Binding NeedlePrintCalibrateParameter.StartPoint.PointY}"
|
||||
ReadCommand="{mwControls:Action TeachStartPos}"
|
||||
MoveCommand="{mwControls:Action MoveToStartPos}"
|
||||
IsReadOnly="True"/>
|
||||
<!--<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Label VerticalAlignment="Center" Content="X1:"/>
|
||||
<mwControls:NumberBox Value="{Binding NeedlePrintCalibrateParameter.StartPoint.PointX}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Label VerticalAlignment="Center" Content="Y1:"/>
|
||||
<mwControls:NumberBox Value="{Binding NeedlePrintCalibrateParameter.StartPoint.PointY}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Button Margin="2,0" Click="{mwControls:Action TeachStartPos}" Content="示教"/>
|
||||
<Button Margin="2,0" Click="{mwControls:Action MoveToStartPos}" Content="移动"/>
|
||||
</StackPanel>-->
|
||||
<Label Content="尾点设置:"/>
|
||||
<customControl:AxisMoveControl LableContent1="X2(mm):"
|
||||
Value1="{Binding NeedlePrintCalibrateParameter.EndPoint.PointX}"
|
||||
LableContent2="Y2(mm):"
|
||||
Value2="{Binding NeedlePrintCalibrateParameter.EndPoint.PointY}"
|
||||
ReadCommand="{mwControls:Action TeachEndPos}"
|
||||
MoveCommand="{mwControls:Action MoveToEndPos}"
|
||||
IsReadOnly="True"/>
|
||||
<!--<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Label VerticalAlignment="Center" Content="X1:"/>
|
||||
<mwControls:NumberBox Value="{Binding NeedlePrintCalibrateParameter.EndPoint.PointX}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Label VerticalAlignment="Center" Content="Y1:"/>
|
||||
<mwControls:NumberBox Value="{Binding NeedlePrintCalibrateParameter.EndPoint.PointY}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Button Margin="2,0" Click="{mwControls:Action TeachEndPos}" Content="示教"/>
|
||||
<Button Margin="2,0" Click="{mwControls:Action MoveToEndPos}" Content="移动"/>
|
||||
</StackPanel>-->
|
||||
<Label Content="间距设置:"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" Content="Xpitch:"/>
|
||||
<mwControls:NumberBox mwControls:NumericKeypadAttach.IsEnabled="True" Value="{Binding NeedlePrintCalibrateParameter.Xpitch}" IsReadOnly="False" Width="80" Margin="4,0" />
|
||||
<Label VerticalAlignment="Center" Content="Ypitch:"/>
|
||||
<mwControls:NumberBox mwControls:NumericKeypadAttach.IsEnabled="True" Value="{Binding NeedlePrintCalibrateParameter.Ypitch}" IsReadOnly="False" Width="80" Margin="4,0" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
<GroupBox Margin="2" Header="【第六步】针印检验">
|
||||
<GroupBox.Content>
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Button IsEnabled="{Binding UiEnable}" Click="{mwControls:Action StartVerify}" Content="开始校验"/>
|
||||
<Button IsEnabled="{Binding UiEnable,Converter={StaticResource boolToInversionConverter}}" Click="{mwControls:Action StopVerify}" Content="停止校验"/>
|
||||
<Button IsEnabled="{Binding UiEnable}" Click="{mwControls:Action SaveParam}" Content="保存"/>
|
||||
<Button IsEnabled="{Binding UiEnable}" Click="{mwControls:Action ResetRecord}" Content="重置记录"/>
|
||||
</StackPanel>
|
||||
<StackPanel IsEnabled="{Binding UiEnable}" Margin="0,2" Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Button Click="{mwControls:Action NeedleAlignment}" Content="针尖对准"/>
|
||||
<Button Click="{mwControls:Action CameraAlignment}" Content="相机对准"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
<GroupBox IsEnabled="{Binding UiEnable}" Margin="2" Header="【第七步】偏差补偿">
|
||||
<GroupBox.Content>
|
||||
<StackPanel>
|
||||
<Label Content="当前针尖补偿:" Width="90"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" Content="XOffset:"/>
|
||||
<mwControls:NumberBox Value="{Binding CurrentNeedleOffsetPoint.PointX}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Label VerticalAlignment="Center" Content="YOffsetY:"/>
|
||||
<mwControls:NumberBox Value="{Binding CurrentNeedleOffsetPoint.PointY}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
</StackPanel>
|
||||
<Label Content="针尖点位:"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" Content="X1:"/>
|
||||
<mwControls:NumberBox Value="{Binding CurrentNeedlePoint.PointX}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Label VerticalAlignment="Center" Content="Y1:"/>
|
||||
<mwControls:NumberBox Value="{Binding CurrentNeedlePoint.PointY}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
</StackPanel>
|
||||
<Label Content="相机点位:"/>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Label VerticalAlignment="Center" Content="X1:"/>
|
||||
<mwControls:NumberBox Value="{Binding CameraPoint.PointX}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Label VerticalAlignment="Center" Content="Y1:"/>
|
||||
<mwControls:NumberBox Value="{Binding CameraPoint.PointY}" IsReadOnly="True" Width="80" Margin="4,0" />
|
||||
<Button Margin="2,0" Click="{mwControls:Action TeachCameraPos}" Content="示教"/>
|
||||
<Button Margin="2,0" Content="补偿偏差" Click="{mwControls:Action CalculateOffset}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
</GroupBox.Content>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
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;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace MainShell.DeviceMaintance.View
|
||||
{
|
||||
/// <summary>
|
||||
/// NeedleCameraPrintView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class NeedleCameraPrintView : UserControl
|
||||
{
|
||||
public NeedleCameraPrintView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using MainShell.DeviceMaintance.Model;
|
||||
using MainShell.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class CameraAccuracyCalibrationViewModel: DeviceMaintanceBaseViewModel
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
using MainShell.DeviceMaintance.Model;
|
||||
using MainShell.DeviceMaintance.ViewModel.State;
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Manual.ViewModel.State;
|
||||
using MaxwellFramework.Core.Interfaces;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class CylinderViewModel : Screen, IPage
|
||||
{
|
||||
private readonly IDeviceIoMonitorService _ioMonitorService;
|
||||
private readonly IDeviceCylinderService _cylinderService;
|
||||
private readonly Dictionary<string, List<CylinderSignalState>> _signalMap = new Dictionary<string, List<CylinderSignalState>>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, DeviceIoPointDefinition> _ioDefinitionsByName;
|
||||
|
||||
private CylinderPageState _pageState;
|
||||
public CylinderPageState PageState
|
||||
{
|
||||
get { return _pageState; }
|
||||
set { SetAndNotify(ref _pageState, value); }
|
||||
}
|
||||
|
||||
public CylinderViewModel(IDeviceIoMonitorService ioMonitorService, IDeviceCylinderService cylinderService)
|
||||
{
|
||||
_ioMonitorService = ioMonitorService;
|
||||
_cylinderService = cylinderService;
|
||||
_ioDefinitionsByName = _ioMonitorService.Definitions.ToDictionary(x => x.Name, x => x, StringComparer.OrdinalIgnoreCase);
|
||||
PageState = BuildState();
|
||||
_ioMonitorService.IoChanged += OnIoChanged;
|
||||
_ioMonitorService.Start();
|
||||
}
|
||||
|
||||
protected override void OnViewLoaded()
|
||||
{
|
||||
base.OnViewLoaded();
|
||||
ApplyIoPoints(_ioMonitorService.LatestPoints.Values);
|
||||
InitializePointsAsync();
|
||||
}
|
||||
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
_ioMonitorService.IoChanged -= OnIoChanged;
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
private CylinderPageState BuildState()
|
||||
{
|
||||
var state = new CylinderPageState();
|
||||
_signalMap.Clear();
|
||||
|
||||
foreach (var definition in _cylinderService.Definitions)
|
||||
{
|
||||
var item = new CylinderItemState
|
||||
{
|
||||
Name = definition.Name,
|
||||
Description = definition.Description,
|
||||
Module = definition.Module,
|
||||
ControlTypeText = GetControlTypeText(definition.ControlType)
|
||||
};
|
||||
|
||||
item.ExtendCommand = new ActionCommand(() => ExecuteCylinderAction(definition, item, true), () => !item.IsBusy);
|
||||
item.RetractCommand = new ActionCommand(() => ExecuteCylinderAction(definition, item, false), () => !item.IsBusy);
|
||||
|
||||
for (var i = 0; i < definition.ExtendOutputPoints.Count; i++)
|
||||
{
|
||||
AddOutputSignal(item, definition.ExtendOutputPoints[i], definition.ExtendOutputPoints.Count > 1 ? string.Format("{0}-伸出输出{1}", definition.Name, i + 1) : definition.Name + "-伸出输出");
|
||||
}
|
||||
|
||||
for (var i = 0; i < definition.RetractOutputPoints.Count; i++)
|
||||
{
|
||||
AddOutputSignal(item, definition.RetractOutputPoints[i], definition.RetractOutputPoints.Count > 1 ? string.Format("{0}-缩回输出{1}", definition.Name, i + 1) : definition.Name + "-缩回输出");
|
||||
}
|
||||
|
||||
foreach (var pointReference in definition.ExtendedFeedbackPoints)
|
||||
{
|
||||
AddFeedbackSignal(item, pointReference, definition.Name + "-伸出到位");
|
||||
}
|
||||
|
||||
foreach (var pointReference in definition.RetractedFeedbackPoints)
|
||||
{
|
||||
AddFeedbackSignal(item, pointReference, definition.Name + "-缩回到位");
|
||||
}
|
||||
|
||||
state.Cylinders.Add(item);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
private void AddOutputSignal(CylinderItemState item, string pointReference, string fallbackName)
|
||||
{
|
||||
var definition = ResolveDefinition(pointReference);
|
||||
var signal = new CylinderSignalState
|
||||
{
|
||||
PointReference = pointReference,
|
||||
PointKey = definition?.PointKey,
|
||||
Name = definition != null ? definition.Name : fallbackName,
|
||||
LineNo = definition != null ? definition.LineNo : string.Empty,
|
||||
IsOutput = true
|
||||
};
|
||||
item.OutputSignals.Add(signal);
|
||||
MapSignal(signal, pointReference);
|
||||
}
|
||||
|
||||
private void AddFeedbackSignal(CylinderItemState item, string pointReference, string fallbackName)
|
||||
{
|
||||
var definition = ResolveDefinition(pointReference);
|
||||
var signal = new CylinderSignalState
|
||||
{
|
||||
PointReference = pointReference,
|
||||
PointKey = definition?.PointKey,
|
||||
Name = definition != null ? definition.Name : fallbackName,
|
||||
LineNo = definition != null ? definition.LineNo : string.Empty,
|
||||
IsOutput = false
|
||||
};
|
||||
item.FeedbackSignals.Add(signal);
|
||||
MapSignal(signal, pointReference);
|
||||
}
|
||||
|
||||
private DeviceIoPointDefinition ResolveDefinition(string pointReference)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(pointReference))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
DeviceIoPointDefinition definition;
|
||||
if (_ioDefinitionsByName.TryGetValue(pointReference, out definition))
|
||||
{
|
||||
return definition;
|
||||
}
|
||||
|
||||
int id;
|
||||
if (!int.TryParse(pointReference, out id))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var matches = _ioMonitorService.Definitions.Where(x => x.Id == id).Take(2).ToList();
|
||||
return matches.Count == 1 ? matches[0] : null;
|
||||
}
|
||||
|
||||
private void MapSignal(CylinderSignalState signal, string pointReference)
|
||||
{
|
||||
var key = !string.IsNullOrWhiteSpace(signal.PointKey) ? signal.PointKey : pointReference;
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<CylinderSignalState> signals;
|
||||
if (!_signalMap.TryGetValue(key, out signals))
|
||||
{
|
||||
signals = new List<CylinderSignalState>();
|
||||
_signalMap[key] = signals;
|
||||
}
|
||||
|
||||
signals.Add(signal);
|
||||
}
|
||||
|
||||
private void OnIoChanged(object sender, EventArgs e)
|
||||
{
|
||||
var args = e as MainShell.EventArgsFolder.DeviceIoChangedEventArgs;
|
||||
if (args == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyIoPoints(args.ChangedPoints);
|
||||
}
|
||||
|
||||
private async void InitializePointsAsync()
|
||||
{
|
||||
_ioMonitorService.RequestRefresh();
|
||||
await Task.Delay(150);
|
||||
ApplyIoPoints(_ioMonitorService.LatestPoints.Values);
|
||||
}
|
||||
|
||||
private void ApplyIoPoints(IEnumerable<DeviceIoPointState> points)
|
||||
{
|
||||
if (points == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var point in points)
|
||||
{
|
||||
if (point == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
List<CylinderSignalState> signals;
|
||||
if (!_signalMap.TryGetValue(point.PointKey, out signals))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var signal in signals)
|
||||
{
|
||||
signal.IsOn = point.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteCylinderAction(CylinderDefinition definition, CylinderItemState item, bool extend)
|
||||
{
|
||||
item.IsBusy = true;
|
||||
RaiseCommands(item);
|
||||
|
||||
string failureReason;
|
||||
var result = extend ? _cylinderService.TryExtend(definition.Name, out failureReason) : _cylinderService.TryRetract(definition.Name, out failureReason);
|
||||
|
||||
if (result)
|
||||
{
|
||||
SimulateCylinderFeedback(definition, extend);
|
||||
PageState.LastActionMessage = definition.Name + (extend ? " 执行伸出成功。" : " 执行缩回成功。");
|
||||
}
|
||||
else
|
||||
{
|
||||
PageState.LastActionMessage = string.IsNullOrWhiteSpace(failureReason)
|
||||
? definition.Name + (extend ? " 伸出失败。" : " 缩回失败。")
|
||||
: failureReason;
|
||||
}
|
||||
|
||||
PageState.LastActionTime = DateTime.Now;
|
||||
item.IsBusy = false;
|
||||
RaiseCommands(item);
|
||||
}
|
||||
|
||||
private void SimulateCylinderFeedback(CylinderDefinition definition, bool extend)
|
||||
{
|
||||
foreach (var output in definition.ExtendOutputPoints.SelectMany(GetSignals))
|
||||
{
|
||||
output.IsOn = extend;
|
||||
}
|
||||
|
||||
foreach (var output in definition.RetractOutputPoints.SelectMany(GetSignals))
|
||||
{
|
||||
output.IsOn = !extend;
|
||||
}
|
||||
|
||||
foreach (var feedback in definition.ExtendedFeedbackPoints.SelectMany(GetSignals))
|
||||
{
|
||||
feedback.IsOn = extend;
|
||||
}
|
||||
|
||||
foreach (var feedback in definition.RetractedFeedbackPoints.SelectMany(GetSignals))
|
||||
{
|
||||
feedback.IsOn = !extend;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<CylinderSignalState> GetSignals(string pointReference)
|
||||
{
|
||||
var definition = ResolveDefinition(pointReference);
|
||||
var key = definition != null ? definition.PointKey : pointReference;
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
return Enumerable.Empty<CylinderSignalState>();
|
||||
}
|
||||
|
||||
List<CylinderSignalState> signals;
|
||||
if (_signalMap.TryGetValue(key, out signals))
|
||||
{
|
||||
return signals;
|
||||
}
|
||||
|
||||
return Enumerable.Empty<CylinderSignalState>();
|
||||
}
|
||||
|
||||
private static void RaiseCommands(CylinderItemState item)
|
||||
{
|
||||
var extend = item.ExtendCommand as ActionCommand;
|
||||
if (extend != null)
|
||||
{
|
||||
extend.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
var retract = item.RetractCommand as ActionCommand;
|
||||
if (retract != null)
|
||||
{
|
||||
retract.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetControlTypeText(CylinderControlType controlType)
|
||||
{
|
||||
switch (controlType)
|
||||
{
|
||||
case CylinderControlType.DualOutput:
|
||||
return "双输出控制";
|
||||
case CylinderControlType.MultiOutput:
|
||||
return "多输出单控";
|
||||
default:
|
||||
return "单输出控制";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
using MainShell.EventArgsFolder;
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Manual.Model;
|
||||
using MainShell.DeviceMaintance.ViewModel.State;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class DeviceIoViewModel : OperateViewModelBase
|
||||
{
|
||||
private readonly IDeviceIoMonitorService _ioMonitorService;
|
||||
private readonly Dictionary<string, DeviceIoPointItemState> _pointStateMap = new Dictionary<string, DeviceIoPointItemState>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private DeviceIoPageState _pageState;
|
||||
public DeviceIoPageState PageState
|
||||
{
|
||||
get { return _pageState; }
|
||||
set { SetAndNotify(ref _pageState, value); }
|
||||
}
|
||||
|
||||
public DeviceIoViewModel(IDeviceIoMonitorService ioMonitorService)
|
||||
{
|
||||
_ioMonitorService = ioMonitorService;
|
||||
PageState = BuildState();
|
||||
_ioMonitorService.IoChanged += OnIoChanged;
|
||||
_ioMonitorService.Start();
|
||||
}
|
||||
|
||||
protected override void OnViewLoaded()
|
||||
{
|
||||
base.OnViewLoaded();
|
||||
RefreshFromCurrentPoints();
|
||||
InitializeLatestPointsAsync();
|
||||
}
|
||||
|
||||
protected override void OnDeactivate()
|
||||
{
|
||||
_ioMonitorService.IoChanged -= OnIoChanged;
|
||||
base.OnDeactivate();
|
||||
}
|
||||
|
||||
private DeviceIoPageState BuildState()
|
||||
{
|
||||
var state = new DeviceIoPageState();
|
||||
_pointStateMap.Clear();
|
||||
|
||||
foreach (var moduleGroup in _ioMonitorService.Definitions.GroupBy(x => string.IsNullOrWhiteSpace(x.Module) ? "Default" : x.Module))
|
||||
{
|
||||
var moduleState = new DeviceIoModuleState
|
||||
{
|
||||
Name = moduleGroup.Key
|
||||
};
|
||||
|
||||
foreach (var definition in moduleGroup.OrderBy(x => x.StationNo).ThenBy(x => x.Id).ThenBy(x => x.LineNo))
|
||||
{
|
||||
var item = new DeviceIoPointItemState
|
||||
{
|
||||
Id = definition.Id,
|
||||
PointKey = definition.PointKey,
|
||||
Module = definition.Module,
|
||||
Name = definition.Name,
|
||||
StationNo = definition.StationNo,
|
||||
LineNo = definition.LineNo,
|
||||
Description = definition.Description,
|
||||
IsOutput = definition.Type == IoPointType.Output,
|
||||
IsOn = definition.DefaultValue,
|
||||
IsInverse = definition.IsInverse,
|
||||
CanWrite = definition.Type == IoPointType.Output && definition.Enabled,
|
||||
};
|
||||
|
||||
if (item.IsOutput)
|
||||
{
|
||||
var command = new ActionCommand(() => ToggleOutput(item), () => item.CanWrite);
|
||||
item.ToggleCommand = command;
|
||||
}
|
||||
|
||||
_pointStateMap[item.PointKey] = item;
|
||||
|
||||
if (item.IsOutput)
|
||||
{
|
||||
moduleState.OutputPoints.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
moduleState.InputPoints.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
state.Modules.Add(moduleState);
|
||||
}
|
||||
|
||||
state.IsOnline = _ioMonitorService.IsOnline;
|
||||
return state;
|
||||
}
|
||||
|
||||
private async void InitializeLatestPointsAsync()
|
||||
{
|
||||
_ioMonitorService.RequestRefresh();
|
||||
await Task.Delay(150);
|
||||
RefreshFromCurrentPoints();
|
||||
}
|
||||
|
||||
private void RefreshFromCurrentPoints()
|
||||
{
|
||||
var points = _ioMonitorService.LatestPoints.Values.ToList();
|
||||
ApplyPoints(points);
|
||||
}
|
||||
|
||||
private void OnIoChanged(object sender, EventArgs e)
|
||||
{
|
||||
var args = e as DeviceIoChangedEventArgs;
|
||||
if (args == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyPoints(args.ChangedPoints);
|
||||
PageState.LastRefreshTime = DateTime.Now;
|
||||
}
|
||||
|
||||
private void ApplyPoints(IEnumerable<DeviceIoPointState> points)
|
||||
{
|
||||
if (points == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var hasPoint = false;
|
||||
foreach (var point in points)
|
||||
{
|
||||
if (point == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hasPoint = true;
|
||||
DeviceIoPointItemState item;
|
||||
if (!_pointStateMap.TryGetValue(point.PointKey, out item))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
item.IsOn = point.Value;
|
||||
|
||||
var outputPoint = point as DeviceOutputPointState;
|
||||
item.CanWrite = outputPoint != null && outputPoint.CanWrite;
|
||||
|
||||
var command = item.ToggleCommand as ActionCommand;
|
||||
if (command != null)
|
||||
{
|
||||
command.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
if (hasPoint)
|
||||
{
|
||||
PageState.LastRefreshTime = DateTime.Now;
|
||||
}
|
||||
|
||||
PageState.IsOnline = hasPoint && _ioMonitorService.IsOnline;
|
||||
}
|
||||
|
||||
private void ToggleOutput(DeviceIoPointItemState item)
|
||||
{
|
||||
DeviceIoPointState point;
|
||||
if (!_ioMonitorService.TryGetPoint(item.PointKey, out point))
|
||||
{
|
||||
UpdateWriteResult(item.Name + " 写入失败:未找到输出点。", false);
|
||||
return;
|
||||
}
|
||||
|
||||
var outputPoint = point as DeviceOutputPointState;
|
||||
if (outputPoint == null || !outputPoint.CanWrite)
|
||||
{
|
||||
UpdateWriteResult(item.Name + " 写入失败:输出点不可写。", false);
|
||||
return;
|
||||
}
|
||||
|
||||
var targetState = !item.IsOn;
|
||||
var result = outputPoint.TrySetOutput(targetState);
|
||||
UpdateWriteResult(item.Name + (result ? (targetState ? " 已切换为 ON。" : " 已切换为 OFF。") : " 写入失败。"), result);
|
||||
}
|
||||
|
||||
private void UpdateWriteResult(string message, bool success)
|
||||
{
|
||||
PageState.LastWriteMessage = message;
|
||||
PageState.IsWriteSuccess = success;
|
||||
PageState.LastWriteTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using MainShell.HeightMeasure.ViewModel;
|
||||
using MainShell.Models;
|
||||
using MaxwellFramework.Core.Interfaces;
|
||||
using Stylet;
|
||||
using StyletIoC;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class DeviceMaintanceViewModel : BaseScreen, IPage
|
||||
{
|
||||
public string Name => "MenuDeviceMaint";
|
||||
private const string NEEDLEBASE = "刺晶头维护";
|
||||
private const string IOMONITOR = "IO监控";
|
||||
private const string HARDWARETEST = "硬件维护";
|
||||
private const string LASERCOMPENSATION = "激光补偿";
|
||||
private readonly Dictionary<string, Screen> _viewModelDict = new Dictionary<string, Screen>();
|
||||
public ObservableCollection<MenuItemWrap> MenuItemWraps { get; private set; }
|
||||
|
||||
private MenuItemWrap _selectedMenuItem;
|
||||
|
||||
public MenuItemWrap SelectedMenuItem
|
||||
{
|
||||
get { return _selectedMenuItem; }
|
||||
set
|
||||
{
|
||||
if (SetAndNotify(ref _selectedMenuItem, value))
|
||||
{
|
||||
CurrentScreen = _viewModelDict[value.Header];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Screen _currentScreen;
|
||||
|
||||
public Screen CurrentScreen
|
||||
{
|
||||
get { return _currentScreen; }
|
||||
set { SetAndNotify(ref _currentScreen, value); }
|
||||
}
|
||||
|
||||
private NeedleBaseViewModel _needleBaseViewModel;
|
||||
[Inject]
|
||||
public NeedleBaseViewModel NeedleBaseViewModel
|
||||
{
|
||||
get { return _needleBaseViewModel; }
|
||||
set { _needleBaseViewModel = value; }
|
||||
}
|
||||
|
||||
private IOMaintanceViewModel _ioMaintanceViewModel;
|
||||
[Inject]
|
||||
public IOMaintanceViewModel IOMaintanceViewModel
|
||||
{
|
||||
get { return _ioMaintanceViewModel; }
|
||||
set { _ioMaintanceViewModel = value; }
|
||||
}
|
||||
|
||||
private HardwareTestViewModel _hardwareTestViewModel;
|
||||
[Inject]
|
||||
public HardwareTestViewModel HardwareTestViewModel
|
||||
{
|
||||
get { return _hardwareTestViewModel; }
|
||||
set { _hardwareTestViewModel = value; }
|
||||
}
|
||||
|
||||
private LaserCompensationViewModel _laserCompensationViewModel;
|
||||
[Inject]
|
||||
public LaserCompensationViewModel LaserCompensationViewModel
|
||||
{
|
||||
get { return _laserCompensationViewModel; }
|
||||
set { _laserCompensationViewModel = value; }
|
||||
}
|
||||
|
||||
public DeviceMaintanceViewModel()
|
||||
{
|
||||
InitMenuItems();
|
||||
}
|
||||
|
||||
protected override void OnViewLoaded()
|
||||
{
|
||||
base.OnViewLoaded();
|
||||
if (_viewModelDict.Count == 0)
|
||||
{
|
||||
InitViewModelDict();
|
||||
}
|
||||
|
||||
if (SelectedMenuItem == null)
|
||||
{
|
||||
SelectedMenuItem = MenuItemWraps[0];
|
||||
}
|
||||
}
|
||||
|
||||
private void InitMenuItems()
|
||||
{
|
||||
MenuItemWraps = new ObservableCollection<MenuItemWrap>
|
||||
{
|
||||
new MenuItemWrap() { Header = NEEDLEBASE, Tag = NEEDLEBASE },
|
||||
new MenuItemWrap() { Header = IOMONITOR, Tag = IOMONITOR },
|
||||
new MenuItemWrap() { Header = HARDWARETEST, Tag = HARDWARETEST },
|
||||
new MenuItemWrap() { Header = LASERCOMPENSATION, Tag = LASERCOMPENSATION },
|
||||
};
|
||||
}
|
||||
|
||||
private void InitViewModelDict()
|
||||
{
|
||||
_viewModelDict.Clear();
|
||||
_viewModelDict.Add(NEEDLEBASE, NeedleBaseViewModel);
|
||||
_viewModelDict.Add(IOMONITOR, IOMaintanceViewModel);
|
||||
_viewModelDict.Add(HARDWARETEST, HardwareTestViewModel);
|
||||
_viewModelDict.Add(LASERCOMPENSATION, LaserCompensationViewModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Log;
|
||||
using MainShell.Models;
|
||||
using MwFramework.Device;
|
||||
using MwFramework.Device.DeviceInterface;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class HardwareTestViewModel:BaseScreen
|
||||
{
|
||||
private readonly HardwareManager _device;
|
||||
private IFFUItem _ffuItem1;
|
||||
|
||||
private string _message = "XXXX";
|
||||
public string Message
|
||||
{
|
||||
get
|
||||
{
|
||||
return _message;
|
||||
}
|
||||
set { SetAndNotify(ref _message, value); }
|
||||
}
|
||||
|
||||
private string _waferBarcode = string.Empty;
|
||||
/// <summary>
|
||||
/// 方片扫码枪读取结果
|
||||
/// </summary>
|
||||
public string WaferBarcode
|
||||
{
|
||||
get { return _waferBarcode; }
|
||||
set { SetAndNotify(ref _waferBarcode, value); }
|
||||
}
|
||||
|
||||
private string _glassBarcode = string.Empty;
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// 基板扫码枪读取结果
|
||||
/// </summary>
|
||||
public string GlassBarcode
|
||||
{
|
||||
get { return _glassBarcode; }
|
||||
set { SetAndNotify(ref _glassBarcode, value); }
|
||||
}
|
||||
|
||||
private int _fFURotateSpeed ;
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// 基板扫码枪读取结果
|
||||
/// </summary>
|
||||
public int FFURotateSpeed
|
||||
{
|
||||
get { return _fFURotateSpeed; }
|
||||
set { SetAndNotify(ref _fFURotateSpeed, value); }
|
||||
}
|
||||
|
||||
public HardwareTestViewModel(HardwareManager hardwareManager)
|
||||
{
|
||||
_device = hardwareManager;
|
||||
_ffuItem1 = _device.FFU?.Count > 0 ? _device.FFU[0] : null;
|
||||
}
|
||||
|
||||
public void btnZeroClick()
|
||||
{
|
||||
try
|
||||
{
|
||||
_device.Diastimeter.ZeroReset();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogSysError(ex, true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public void GetDarkReference()
|
||||
{
|
||||
IDeviceParamExtend p = _device.Diastimeter as IDeviceParamExtend;
|
||||
if (p[(CommandStr)"GetDarkReference"].Execute())
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
public void btnGetCurrentValueClick()
|
||||
{
|
||||
try
|
||||
{
|
||||
_device.Diastimeter.GetLastSample(out double Distance);
|
||||
Message = Convert.ToString(Distance);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogSysError(ex, true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void FFURotateSpeedChanged()
|
||||
{
|
||||
if (_ffuItem1 != null)
|
||||
{
|
||||
if (!_ffuItem1.CurrentOnOff) _ffuItem1.OnOff = true;
|
||||
//_deviceDefaltSetting.Write();
|
||||
_ffuItem1.SettingVelocity = FFURotateSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
public void BtnOpenFFU()
|
||||
{
|
||||
if (_ffuItem1 != null)
|
||||
{
|
||||
if (!_ffuItem1.CurrentOnOff) _ffuItem1.OnOff = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void BtnCloseFFU()
|
||||
{
|
||||
if (_ffuItem1 != null)
|
||||
{
|
||||
if (_ffuItem1.CurrentOnOff) _ffuItem1.OnOff = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void btnScanWaferBarcodeClick()
|
||||
{
|
||||
try
|
||||
{
|
||||
//this.WaferBarcode = string.Empty;
|
||||
//_device.WaferBarcodeScanner.TryScan(out string barcode, 1000);
|
||||
//this.WaferBarcode = string.IsNullOrEmpty(barcode) ? "NA" : barcode;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogSysError(ex, true);
|
||||
|
||||
}
|
||||
}
|
||||
public async void btnScanGlassBarcodeClick()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
//this.GlassBarcode = string.Empty;
|
||||
//_device.GlassBarcodeScanner.TryScan(out string barcode, 1000 * 5);
|
||||
//this.GlassBarcode = string.IsNullOrEmpty(barcode) ? "NA" : barcode;
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.LogSysError(ex, true);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using MainShell.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Stylet;
|
||||
using StyletIoC;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class IOMaintanceViewModel : BaseScreen
|
||||
{
|
||||
private IOMonitorViewModel _iOMonitorViewModel;
|
||||
[Inject]
|
||||
public IOMonitorViewModel IOMonitorViewModel
|
||||
{
|
||||
get { return _iOMonitorViewModel; }
|
||||
set { _iOMonitorViewModel = value; }
|
||||
}
|
||||
|
||||
private CylinderViewModel _cylinderViewModel;
|
||||
[Inject]
|
||||
public CylinderViewModel CylinderViewModel
|
||||
{
|
||||
get { return _cylinderViewModel; }
|
||||
set { _cylinderViewModel = value; }
|
||||
}
|
||||
|
||||
private IoTestViewModel _ioTestViewModel;
|
||||
[Inject]
|
||||
public IoTestViewModel IoTestViewModel
|
||||
{
|
||||
get { return _ioTestViewModel; }
|
||||
set { _ioTestViewModel = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MaxwellFramework.Core.Interfaces;
|
||||
using MwFramework.Device;
|
||||
using MwFramework.ManagerService;
|
||||
using StyletIoC;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class IOMonitorViewModel:Screen,IPage
|
||||
{
|
||||
private DeviceIoViewModel _deviceIoViewModel;
|
||||
[Inject]
|
||||
public DeviceIoViewModel DeviceIoViewModel
|
||||
{
|
||||
get { return _deviceIoViewModel; }
|
||||
set { _deviceIoViewModel = value; }
|
||||
}
|
||||
|
||||
//private IDIO ioprop;
|
||||
//public IDIO IOProp
|
||||
//{
|
||||
// get { return ioprop; }
|
||||
// set
|
||||
// {
|
||||
// ioprop = value;
|
||||
// OnPropertyChanged("IOProp");
|
||||
// }
|
||||
//}
|
||||
|
||||
//public IOMonitorViewModel(IDeviceManager manager)
|
||||
//{
|
||||
// IDeviceList dlist = (IDeviceList)manager;
|
||||
// IOProp = dlist.GetDevice<IDIO>("PLCIO");
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,533 @@
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Log;
|
||||
using MainShell.Models;
|
||||
using MwFramework.Device.Delta;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class IoTestViewModel : BaseScreen
|
||||
{
|
||||
public class DeltaBitTestState : PropertyChangedBase
|
||||
{
|
||||
private int _cardNo;
|
||||
public int CardNo
|
||||
{
|
||||
get { return _cardNo; }
|
||||
set { SetAndNotify(ref _cardNo, value); }
|
||||
}
|
||||
|
||||
private int _node;
|
||||
public int Node
|
||||
{
|
||||
get { return _node; }
|
||||
set { SetAndNotify(ref _node, value); }
|
||||
}
|
||||
|
||||
private int _slot;
|
||||
public int Slot
|
||||
{
|
||||
get { return _slot; }
|
||||
set { SetAndNotify(ref _slot, value); }
|
||||
}
|
||||
|
||||
private int _index;
|
||||
public int Index
|
||||
{
|
||||
get { return _index; }
|
||||
set { SetAndNotify(ref _index, value); }
|
||||
}
|
||||
|
||||
private int _subIndex;
|
||||
public int SubIndex
|
||||
{
|
||||
get { return _subIndex; }
|
||||
set { SetAndNotify(ref _subIndex, value); }
|
||||
}
|
||||
|
||||
private int _bitNo;
|
||||
public int BitNo
|
||||
{
|
||||
get { return _bitNo; }
|
||||
set { SetAndNotify(ref _bitNo, value); }
|
||||
}
|
||||
|
||||
private int _ioType = 1;
|
||||
public int IoType
|
||||
{
|
||||
get { return _ioType; }
|
||||
set { SetAndNotify(ref _ioType, value); }
|
||||
}
|
||||
|
||||
private int _readIoType = 1;
|
||||
public int ReadIoType
|
||||
{
|
||||
get { return _readIoType; }
|
||||
set { SetAndNotify(ref _readIoType, value); }
|
||||
}
|
||||
|
||||
private bool _writeValue;
|
||||
public bool WriteValue
|
||||
{
|
||||
get { return _writeValue; }
|
||||
set { SetAndNotify(ref _writeValue, value); }
|
||||
}
|
||||
|
||||
private bool _readValue;
|
||||
public bool ReadValue
|
||||
{
|
||||
get { return _readValue; }
|
||||
set { SetAndNotify(ref _readValue, value); }
|
||||
}
|
||||
|
||||
private ushort _returnCode;
|
||||
public ushort ReturnCode
|
||||
{
|
||||
get { return _returnCode; }
|
||||
set { SetAndNotify(ref _returnCode, value); }
|
||||
}
|
||||
|
||||
private string _resultMessage = string.Empty;
|
||||
public string ResultMessage
|
||||
{
|
||||
get { return _resultMessage; }
|
||||
set { SetAndNotify(ref _resultMessage, value); }
|
||||
}
|
||||
}
|
||||
|
||||
public class DeltaDaTestState : PropertyChangedBase
|
||||
{
|
||||
private int _cardNo;
|
||||
public int CardNo
|
||||
{
|
||||
get { return _cardNo; }
|
||||
set { SetAndNotify(ref _cardNo, value); }
|
||||
}
|
||||
|
||||
private int _node;
|
||||
public int Node
|
||||
{
|
||||
get { return _node; }
|
||||
set { SetAndNotify(ref _node, value); }
|
||||
}
|
||||
|
||||
private int _slot;
|
||||
public int Slot
|
||||
{
|
||||
get { return _slot; }
|
||||
set { SetAndNotify(ref _slot, value); }
|
||||
}
|
||||
|
||||
private int _index;
|
||||
public int Index
|
||||
{
|
||||
get { return _index; }
|
||||
set { SetAndNotify(ref _index, value); }
|
||||
}
|
||||
|
||||
private int _subIndex;
|
||||
public int SubIndex
|
||||
{
|
||||
get { return _subIndex; }
|
||||
set { SetAndNotify(ref _subIndex, value); }
|
||||
}
|
||||
|
||||
private int _byteSize = 2;
|
||||
public int ByteSize
|
||||
{
|
||||
get { return _byteSize; }
|
||||
set { SetAndNotify(ref _byteSize, value); }
|
||||
}
|
||||
|
||||
private bool _signed = true;
|
||||
public bool Signed
|
||||
{
|
||||
get { return _signed; }
|
||||
set { SetAndNotify(ref _signed, value); }
|
||||
}
|
||||
|
||||
private int _ioType = 1;
|
||||
public int IoType
|
||||
{
|
||||
get { return _ioType; }
|
||||
set { SetAndNotify(ref _ioType, value); }
|
||||
}
|
||||
|
||||
private int _writeRawValue;
|
||||
public int WriteRawValue
|
||||
{
|
||||
get { return _writeRawValue; }
|
||||
set { SetAndNotify(ref _writeRawValue, value); }
|
||||
}
|
||||
|
||||
private int _readRawValue;
|
||||
public int ReadRawValue
|
||||
{
|
||||
get { return _readRawValue; }
|
||||
set { SetAndNotify(ref _readRawValue, value); }
|
||||
}
|
||||
|
||||
private ushort _returnCode;
|
||||
public ushort ReturnCode
|
||||
{
|
||||
get { return _returnCode; }
|
||||
set { SetAndNotify(ref _returnCode, value); }
|
||||
}
|
||||
|
||||
private string _resultMessage = string.Empty;
|
||||
public string ResultMessage
|
||||
{
|
||||
get { return _resultMessage; }
|
||||
set { SetAndNotify(ref _resultMessage, value); }
|
||||
}
|
||||
}
|
||||
|
||||
private readonly HardwareManager _hardwareManager;
|
||||
|
||||
private string _cardStatusText;
|
||||
public string CardStatusText
|
||||
{
|
||||
get { return _cardStatusText; }
|
||||
set { SetAndNotify(ref _cardStatusText, value); }
|
||||
}
|
||||
|
||||
public DeltaBitTestState BitState { get; private set; }
|
||||
|
||||
public DeltaDaTestState DaState { get; private set; }
|
||||
|
||||
public IoTestViewModel(HardwareManager hardwareManager)
|
||||
{
|
||||
if (hardwareManager == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(hardwareManager));
|
||||
}
|
||||
|
||||
_hardwareManager = hardwareManager;
|
||||
BitState = BuildBitState();
|
||||
DaState = BuildDaState();
|
||||
RefreshCardStatus();
|
||||
}
|
||||
|
||||
protected override void OnViewLoaded()
|
||||
{
|
||||
base.OnViewLoaded();
|
||||
RefreshCardStatus();
|
||||
}
|
||||
|
||||
public void RefreshCardStatus()
|
||||
{
|
||||
IDeltaIoExtend deltaIoExtend;
|
||||
bool available = _hardwareManager.TryGetDeltaIoExtend(out deltaIoExtend);
|
||||
CardStatusText = available ? $"Delta卡已连接:{_hardwareManager.TdCard.GetType().FullName}" : "Delta卡未初始化或未实现 IDeltaIoExtend";
|
||||
}
|
||||
|
||||
public void ReadBit()
|
||||
{
|
||||
try
|
||||
{
|
||||
IDeltaIoExtend deltaIoExtend;
|
||||
if (!TryGetDeltaIoExtend(out deltaIoExtend))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ushort cardNo;
|
||||
ushort node;
|
||||
ushort slot;
|
||||
ushort index;
|
||||
ushort subIndex;
|
||||
byte bitNo;
|
||||
ushort ioType;
|
||||
if (!TryGetBitReadParameters(out cardNo, out node, out slot, out index, out subIndex, out bitNo, out ioType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool value;
|
||||
ushort result = deltaIoExtend.ReadBit(cardNo, node, slot, index, subIndex, bitNo, out value, ioType);
|
||||
BitState.ReadValue = value;
|
||||
BitState.ReturnCode = result;
|
||||
BitState.ResultMessage = $"ReadBit 返回码:{result},结果:{value}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex, BitState, "ReadBit 执行异常");
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteBit()
|
||||
{
|
||||
try
|
||||
{
|
||||
IDeltaIoExtend deltaIoExtend;
|
||||
if (!TryGetDeltaIoExtend(out deltaIoExtend))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ushort cardNo;
|
||||
ushort node;
|
||||
ushort slot;
|
||||
ushort index;
|
||||
ushort subIndex;
|
||||
byte bitNo;
|
||||
ushort readIoType;
|
||||
if (!TryGetBitWriteParameters(out cardNo, out node, out slot, out index, out subIndex, out bitNo, out readIoType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ushort result = deltaIoExtend.WriteBit(cardNo, node, slot, index, subIndex, bitNo, BitState.WriteValue, readIoType);
|
||||
BitState.ReturnCode = result;
|
||||
BitState.ResultMessage = $"WriteBit 返回码:{result},写入值:{BitState.WriteValue}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex, BitState, "WriteBit 执行异常");
|
||||
}
|
||||
}
|
||||
|
||||
public void ReadDa()
|
||||
{
|
||||
try
|
||||
{
|
||||
IDeltaIoExtend deltaIoExtend;
|
||||
if (!TryGetDeltaIoExtend(out deltaIoExtend))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ushort cardNo;
|
||||
ushort node;
|
||||
ushort slot;
|
||||
ushort index;
|
||||
ushort subIndex;
|
||||
ushort byteSize;
|
||||
ushort ioType;
|
||||
if (!TryGetDaReadParameters(out cardNo, out node, out slot, out index, out subIndex, out byteSize, out ioType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int rawValue;
|
||||
ushort result = deltaIoExtend.ReadDA(cardNo, node, slot, index, subIndex, out rawValue, byteSize, DaState.Signed, ioType);
|
||||
DaState.ReadRawValue = rawValue;
|
||||
DaState.ReturnCode = result;
|
||||
DaState.ResultMessage = $"ReadDA 返回码:{result},结果:{rawValue}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex, DaState, "ReadDA 执行异常");
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteDa()
|
||||
{
|
||||
try
|
||||
{
|
||||
IDeltaIoExtend deltaIoExtend;
|
||||
if (!TryGetDeltaIoExtend(out deltaIoExtend))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ushort cardNo;
|
||||
ushort node;
|
||||
ushort slot;
|
||||
ushort index;
|
||||
ushort subIndex;
|
||||
ushort byteSize;
|
||||
if (!TryGetDaWriteParameters(out cardNo, out node, out slot, out index, out subIndex, out byteSize))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ushort result = deltaIoExtend.WriteDA(cardNo, node, slot, index, subIndex, DaState.WriteRawValue, byteSize);
|
||||
DaState.ReturnCode = result;
|
||||
DaState.ResultMessage = $"WriteDA 返回码:{result},写入值:{DaState.WriteRawValue}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex, DaState, "WriteDA 执行异常");
|
||||
}
|
||||
}
|
||||
|
||||
private DeltaBitTestState BuildBitState()
|
||||
{
|
||||
DeltaBitTestState state = new DeltaBitTestState();
|
||||
state.CardNo = 0;
|
||||
state.Node = 0;
|
||||
state.Slot = 0;
|
||||
state.Index = 0;
|
||||
state.SubIndex = 0;
|
||||
state.BitNo = 0;
|
||||
state.IoType = 1;
|
||||
state.ReadIoType = 1;
|
||||
return state;
|
||||
}
|
||||
|
||||
private DeltaDaTestState BuildDaState()
|
||||
{
|
||||
DeltaDaTestState state = new DeltaDaTestState();
|
||||
state.CardNo = 0;
|
||||
state.Node = 0;
|
||||
state.Slot = 0;
|
||||
state.Index = 0;
|
||||
state.SubIndex = 0;
|
||||
state.ByteSize = 2;
|
||||
state.IoType = 1;
|
||||
return state;
|
||||
}
|
||||
|
||||
private bool TryGetDeltaIoExtend(out IDeltaIoExtend deltaIoExtend)
|
||||
{
|
||||
RefreshCardStatus();
|
||||
if (_hardwareManager.TryGetDeltaIoExtend(out deltaIoExtend))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BitState.ResultMessage = "Delta卡未初始化或未实现 IDeltaIoExtend";
|
||||
DaState.ResultMessage = BitState.ResultMessage;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetBitReadParameters(out ushort cardNo, out ushort node, out ushort slot, out ushort index, out ushort subIndex, out byte bitNo, out ushort ioType)
|
||||
{
|
||||
cardNo = 0;
|
||||
node = 0;
|
||||
slot = 0;
|
||||
index = 0;
|
||||
subIndex = 0;
|
||||
bitNo = 0;
|
||||
ioType = 0;
|
||||
|
||||
bool isValid = TryGetUInt16(BitState.CardNo, "CardNo", out cardNo) &&
|
||||
TryGetUInt16(BitState.Node, "Node", out node) &&
|
||||
TryGetUInt16(BitState.Slot, "Slot", out slot) &&
|
||||
TryGetHexUInt16(BitState.Index, "Index", out index) &&
|
||||
TryGetHexUInt16(BitState.SubIndex, "SubIndex", out subIndex) &&
|
||||
TryGetByte(BitState.BitNo, "BitNo", out bitNo) &&
|
||||
TryGetUInt16(BitState.IoType, "IoType", out ioType);
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private bool TryGetBitWriteParameters(out ushort cardNo, out ushort node, out ushort slot, out ushort index, out ushort subIndex, out byte bitNo, out ushort readIoType)
|
||||
{
|
||||
cardNo = 0;
|
||||
node = 0;
|
||||
slot = 0;
|
||||
index = 0;
|
||||
subIndex = 0;
|
||||
bitNo = 0;
|
||||
readIoType = 0;
|
||||
|
||||
bool isValid = TryGetUInt16(BitState.CardNo, "CardNo", out cardNo) &&
|
||||
TryGetUInt16(BitState.Node, "Node", out node) &&
|
||||
TryGetUInt16(BitState.Slot, "Slot", out slot) &&
|
||||
TryGetHexUInt16(BitState.Index, "Index", out index) &&
|
||||
TryGetHexUInt16(BitState.SubIndex, "SubIndex", out subIndex) &&
|
||||
TryGetByte(BitState.BitNo, "BitNo", out bitNo) &&
|
||||
TryGetUInt16(BitState.ReadIoType, "ReadIoType", out readIoType);
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private bool TryGetDaReadParameters(out ushort cardNo, out ushort node, out ushort slot, out ushort index, out ushort subIndex, out ushort byteSize, out ushort ioType)
|
||||
{
|
||||
cardNo = 0;
|
||||
node = 0;
|
||||
slot = 0;
|
||||
index = 0;
|
||||
subIndex = 0;
|
||||
byteSize = 0;
|
||||
ioType = 0;
|
||||
|
||||
bool isValid = TryGetUInt16(DaState.CardNo, "CardNo", out cardNo) &&
|
||||
TryGetUInt16(DaState.Node, "Node", out node) &&
|
||||
TryGetUInt16(DaState.Slot, "Slot", out slot) &&
|
||||
TryGetHexUInt16(DaState.Index, "Index", out index) &&
|
||||
TryGetHexUInt16(DaState.SubIndex, "SubIndex", out subIndex) &&
|
||||
TryGetUInt16(DaState.ByteSize, "ByteSize", out byteSize) &&
|
||||
TryGetUInt16(DaState.IoType, "IoType", out ioType);
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private bool TryGetDaWriteParameters(out ushort cardNo, out ushort node, out ushort slot, out ushort index, out ushort subIndex, out ushort byteSize)
|
||||
{
|
||||
cardNo = 0;
|
||||
node = 0;
|
||||
slot = 0;
|
||||
index = 0;
|
||||
subIndex = 0;
|
||||
byteSize = 0;
|
||||
|
||||
bool isValid = TryGetUInt16(DaState.CardNo, "CardNo", out cardNo) &&
|
||||
TryGetUInt16(DaState.Node, "Node", out node) &&
|
||||
TryGetUInt16(DaState.Slot, "Slot", out slot) &&
|
||||
TryGetHexUInt16(DaState.Index, "Index", out index) &&
|
||||
TryGetHexUInt16(DaState.SubIndex, "SubIndex", out subIndex) &&
|
||||
TryGetUInt16(DaState.ByteSize, "ByteSize", out byteSize);
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private bool TryGetHexUInt16(int sourceValue, string parameterName, out ushort value)
|
||||
{
|
||||
string hexText = sourceValue.ToString(CultureInfo.InvariantCulture);
|
||||
return ushort.TryParse(hexText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out value)
|
||||
? true
|
||||
: SetHexUInt16Error(parameterName, out value);
|
||||
}
|
||||
|
||||
private bool SetHexUInt16Error(string parameterName, out ushort value)
|
||||
{
|
||||
value = 0;
|
||||
string message = $"参数 {parameterName} 超出十六进制 ushort 范围。";
|
||||
BitState.ResultMessage = message;
|
||||
DaState.ResultMessage = message;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TryGetUInt16(int sourceValue, string parameterName, out ushort value)
|
||||
{
|
||||
if (sourceValue < ushort.MinValue || sourceValue > ushort.MaxValue)
|
||||
{
|
||||
value = 0;
|
||||
string message = $"参数 {parameterName} 超出 ushort 范围。";
|
||||
BitState.ResultMessage = message;
|
||||
DaState.ResultMessage = message;
|
||||
return false;
|
||||
}
|
||||
|
||||
value = (ushort)sourceValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryGetByte(int sourceValue, string parameterName, out byte value)
|
||||
{
|
||||
if (sourceValue < byte.MinValue || sourceValue > byte.MaxValue)
|
||||
{
|
||||
value = 0;
|
||||
string message = $"参数 {parameterName} 超出 byte 范围。";
|
||||
BitState.ResultMessage = message;
|
||||
return false;
|
||||
}
|
||||
|
||||
value = (byte)sourceValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void HandleException(Exception ex, DeltaBitTestState state, string operationName)
|
||||
{
|
||||
state.ResultMessage = operationName;
|
||||
LogManager.LogSysError(ex, true);
|
||||
}
|
||||
|
||||
private void HandleException(Exception ex, DeltaDaTestState state, string operationName)
|
||||
{
|
||||
state.ResultMessage = operationName;
|
||||
LogManager.LogSysError(ex, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,446 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Hardware;
|
||||
using MainShell.DeviceMaintance.Model;
|
||||
using MainShell.Log;
|
||||
using MainShell.Motion;
|
||||
using MaxwellFramework.Core.Interfaces;
|
||||
using Stylet;
|
||||
using StyletIoC;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MwFramework.Device;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class LaserCompensationViewModel : DeviceMaintanceBaseViewModel, IPage
|
||||
{
|
||||
private const string ProjectPageName = "激光补偿";
|
||||
private const int MinimumMoveTimeoutMilliseconds = 15000;
|
||||
private const double MoveTimeoutScaleFactor = 3d;
|
||||
private const int MoveTimeoutExtraMilliseconds = 2000;
|
||||
|
||||
private readonly SafeAxisMotion _safeAxisMotion;
|
||||
private readonly AxisSpeedManager _axisSpeedManager;
|
||||
private readonly HardwareManager _hardwareManager;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
private bool _uiEnable = true;
|
||||
private bool _isRunning;
|
||||
private string _statusMessage;
|
||||
private int _currentLoopIndex;
|
||||
private int _currentPointIndex;
|
||||
private double _currentTargetPosition;
|
||||
private string _selectedAxisName;
|
||||
|
||||
public LaserCompensationViewModel(SafeAxisMotion safeAxisMotion, AxisSpeedManager axisSpeedManager, HardwareManager hardwareManager)
|
||||
{
|
||||
_safeAxisMotion = safeAxisMotion;
|
||||
_axisSpeedManager = axisSpeedManager;
|
||||
_hardwareManager = hardwareManager;
|
||||
Setting = new LaserCompensationSetting();
|
||||
Setting.LoadFromFile();
|
||||
AxisNames = new System.Collections.ObjectModel.ObservableCollection<string>(BuildAxisNames());
|
||||
if (!string.IsNullOrWhiteSpace(Setting.AxisName) && AxisNames.Contains(Setting.AxisName))
|
||||
{
|
||||
SelectedAxisName = Setting.AxisName;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedAxisName = AxisNames.FirstOrDefault();
|
||||
}
|
||||
StatusMessage = "待机";
|
||||
}
|
||||
|
||||
public string Name => "LaserCompensationMaint";
|
||||
|
||||
public LaserCompensationSetting Setting { get; }
|
||||
|
||||
public System.Collections.ObjectModel.ObservableCollection<string> AxisNames { get; }
|
||||
|
||||
public string SelectedAxisName
|
||||
{
|
||||
get { return _selectedAxisName; }
|
||||
set
|
||||
{
|
||||
if (SetAndNotify(ref _selectedAxisName, value))
|
||||
{
|
||||
Setting.AxisName = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool UiEnable
|
||||
{
|
||||
get { return _uiEnable; }
|
||||
set
|
||||
{
|
||||
if (SetAndNotify(ref _uiEnable, value))
|
||||
{
|
||||
OnUiStateChanged(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRunning
|
||||
{
|
||||
get { return _isRunning; }
|
||||
set { SetAndNotify(ref _isRunning, value); }
|
||||
}
|
||||
|
||||
public string StatusMessage
|
||||
{
|
||||
get { return _statusMessage; }
|
||||
set { SetAndNotify(ref _statusMessage, value); }
|
||||
}
|
||||
|
||||
public int CurrentLoopIndex
|
||||
{
|
||||
get { return _currentLoopIndex; }
|
||||
set { SetAndNotify(ref _currentLoopIndex, value); }
|
||||
}
|
||||
|
||||
public int CurrentPointIndex
|
||||
{
|
||||
get { return _currentPointIndex; }
|
||||
set { SetAndNotify(ref _currentPointIndex, value); }
|
||||
}
|
||||
|
||||
public double CurrentTargetPosition
|
||||
{
|
||||
get { return _currentTargetPosition; }
|
||||
set { SetAndNotify(ref _currentTargetPosition, value); }
|
||||
}
|
||||
|
||||
public async Task StartAsync()
|
||||
{
|
||||
if (IsRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string validationMessage = ValidateSetting();
|
||||
if (!string.IsNullOrWhiteSpace(validationMessage))
|
||||
{
|
||||
StatusMessage = validationMessage;
|
||||
LocalizedMessageBox.Show(MessageKey.ParamInvalid, MessageKey.TitleError, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
UiEnable = false;
|
||||
IsRunning = true;
|
||||
CurrentLoopIndex = 0;
|
||||
CurrentPointIndex = 0;
|
||||
CurrentTargetPosition = 0d;
|
||||
Setting.AxisName = SelectedAxisName;
|
||||
StatusMessage = "激光补偿运行中";
|
||||
|
||||
IoC.Get<IProjectManager>().EnablePageAndDisableOther(ProjectPageName);
|
||||
BuildStartLogMessage().LogInfo();
|
||||
|
||||
try
|
||||
{
|
||||
CancellationToken cancellationToken = _cancellationTokenSource.Token;
|
||||
await ExecuteCompensationAsync(cancellationToken).ConfigureAwait(true);
|
||||
|
||||
StatusMessage = "激光补偿执行完成";
|
||||
BuildFinishLogMessage("完成").LogInfo();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
StatusMessage = "激光补偿已停止";
|
||||
BuildFinishLogMessage("已停止").LogInfo();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusMessage = $"激光补偿异常:{ex.Message}";
|
||||
LogManager.LogSysError(ex, true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsRunning = false;
|
||||
UiEnable = true;
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
IoC.Get<IProjectManager>().SwitchState();
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
if (!IsRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StatusMessage = "正在停止激光补偿";
|
||||
"激光补偿收到停止请求".LogInfo();
|
||||
_cancellationTokenSource?.Cancel();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
try
|
||||
{
|
||||
Setting.SaveToFile();
|
||||
StatusMessage = "参数已保存";
|
||||
"激光补偿参数已保存".LogInfo();
|
||||
LocalizedMessageBox.Show(MessageKey.CommonSaveSucceeded, MessageKey.TitleInfo, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusMessage = $"参数保存失败:{ex.Message}";
|
||||
LogManager.LogSysError(ex, true);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ExecuteCompensationAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
IReadOnlyList<double> trajectory = BuildTrajectory();
|
||||
|
||||
ApplyAxisSpeedIfPossible();
|
||||
|
||||
for (int workIndex = 0; workIndex < Setting.WorkCount; workIndex++)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
CurrentLoopIndex = workIndex + 1;
|
||||
$"激光补偿开始第{CurrentLoopIndex}次循环,总点数={trajectory.Count}".LogInfo();
|
||||
|
||||
for (int pointIndex = 0; pointIndex < trajectory.Count; pointIndex++)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
double targetPosition = trajectory[pointIndex];
|
||||
CurrentPointIndex = pointIndex + 1;
|
||||
CurrentTargetPosition = targetPosition;
|
||||
StatusMessage = $"循环 {CurrentLoopIndex}/{Setting.WorkCount},点位 {CurrentPointIndex}/{trajectory.Count}";
|
||||
|
||||
int timeoutMilliseconds = CalculateMoveTimeoutMilliseconds(targetPosition, trajectory, pointIndex);
|
||||
$"激光补偿移动开始:轴={Setting.AxisName},循环={CurrentLoopIndex},点位={CurrentPointIndex},目标={targetPosition:F4},超时={timeoutMilliseconds}ms".LogInfo();
|
||||
|
||||
MotionResult motionResult = await _safeAxisMotion.MoveAbsAsync(
|
||||
Setting.AxisName,
|
||||
targetPosition,
|
||||
timeoutMilliseconds,
|
||||
cancellationToken,
|
||||
alarmId: null).ConfigureAwait(false);
|
||||
|
||||
motionResult.EnsureSuccess();
|
||||
|
||||
$"激光补偿移动完成:轴={Setting.AxisName},循环={CurrentLoopIndex},点位={CurrentPointIndex},目标={targetPosition:F4},到位={motionResult.EndPosition:F4}".LogInfo();
|
||||
|
||||
if (Setting.DwellTime > 0d)
|
||||
{
|
||||
int dwellMilliseconds = (int)Math.Ceiling(Setting.DwellTime * 1000d);
|
||||
$"激光补偿延时采样:{dwellMilliseconds}ms".LogInfo();
|
||||
await Task.Delay(dwellMilliseconds, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyAxisSpeedIfPossible()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(Setting.AxisName) && Setting.Speed > 0d)
|
||||
{
|
||||
_axisSpeedManager.SetAxisSpeed(Setting.AxisName, Setting.Speed);
|
||||
$"激光补偿轴速度已设置:轴={Setting.AxisName},Speed={Setting.Speed:F4}".LogInfo();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
$"激光补偿轴速度设置失败:{ex}".LogSysError();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private IReadOnlyList<double> BuildTrajectory()
|
||||
{
|
||||
List<double> measurePoints = Enumerable.Range(0, Setting.StepsCount)
|
||||
.Select(index => Setting.StartPos + index * Setting.Steps)
|
||||
.ToList();
|
||||
|
||||
double readyPosition = Setting.StartPos - Setting.JumpPos;
|
||||
double overshootPosition = measurePoints[measurePoints.Count - 1] + Setting.JumpPos;
|
||||
|
||||
List<double> trajectory = new List<double>(measurePoints.Count * 2 + 3)
|
||||
{
|
||||
readyPosition
|
||||
};
|
||||
|
||||
trajectory.AddRange(measurePoints);
|
||||
trajectory.Add(overshootPosition);
|
||||
trajectory.AddRange(measurePoints.AsEnumerable().Reverse());
|
||||
trajectory.Add(readyPosition);
|
||||
|
||||
return trajectory;
|
||||
}
|
||||
|
||||
private int CalculateMoveTimeoutMilliseconds(double targetPosition, IReadOnlyList<double> trajectory, int pointIndex)
|
||||
{
|
||||
IAxis axis = _hardwareManager.GetAxisByName(Setting.AxisName);
|
||||
double startPosition = GetMoveStartPosition(axis, trajectory, pointIndex, targetPosition);
|
||||
double distance = Math.Abs(targetPosition - startPosition);
|
||||
double speed = ResolvePositiveMotionParameter(axis != null ? axis.Param.Velocity : 0d, Math.Abs(Setting.Speed));
|
||||
if (speed <= 0d)
|
||||
{
|
||||
return MinimumMoveTimeoutMilliseconds;
|
||||
}
|
||||
|
||||
double acceleration = ResolvePositiveMotionParameter(axis != null ? axis.Param.Accelerate : 0d, 0d);
|
||||
double deceleration = ResolvePositiveMotionParameter(axis != null ? axis.Param.Decelerate : 0d, acceleration);
|
||||
double expectedMilliseconds = CalculateExpectedMoveMilliseconds(distance, speed, acceleration, deceleration);
|
||||
|
||||
return Math.Max(MinimumMoveTimeoutMilliseconds, (int)Math.Ceiling(expectedMilliseconds * MoveTimeoutScaleFactor + MoveTimeoutExtraMilliseconds));
|
||||
}
|
||||
|
||||
private static double GetMoveStartPosition(IAxis axis, IReadOnlyList<double> trajectory, int pointIndex, double targetPosition)
|
||||
{
|
||||
if (pointIndex > 0)
|
||||
{
|
||||
return trajectory[pointIndex - 1];
|
||||
}
|
||||
|
||||
if (axis != null)
|
||||
{
|
||||
return axis.State != null ? axis.State.ActualPos : axis.GetPositionImmediate();
|
||||
}
|
||||
|
||||
return targetPosition;
|
||||
}
|
||||
|
||||
private static double ResolvePositiveMotionParameter(double primaryValue, double fallbackValue)
|
||||
{
|
||||
if (!double.IsNaN(primaryValue) && !double.IsInfinity(primaryValue) && primaryValue > 0d)
|
||||
{
|
||||
return primaryValue;
|
||||
}
|
||||
|
||||
if (!double.IsNaN(fallbackValue) && !double.IsInfinity(fallbackValue) && fallbackValue > 0d)
|
||||
{
|
||||
return fallbackValue;
|
||||
}
|
||||
|
||||
return 0d;
|
||||
}
|
||||
|
||||
private static double CalculateExpectedMoveMilliseconds(double distance, double speed, double acceleration, double deceleration)
|
||||
{
|
||||
if (distance <= 0d)
|
||||
{
|
||||
return 0d;
|
||||
}
|
||||
|
||||
if (speed <= 0d)
|
||||
{
|
||||
return 0d;
|
||||
}
|
||||
|
||||
if (acceleration <= 0d || deceleration <= 0d)
|
||||
{
|
||||
return distance / speed * 1000d;
|
||||
}
|
||||
|
||||
double accelerateDistance = speed * speed / (2d * acceleration);
|
||||
double decelerateDistance = speed * speed / (2d * deceleration);
|
||||
double criticalDistance = accelerateDistance + decelerateDistance;
|
||||
double expectedSeconds;
|
||||
|
||||
if (distance >= criticalDistance)
|
||||
{
|
||||
expectedSeconds = speed / acceleration + speed / deceleration + (distance - criticalDistance) / speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
double peakSpeed = Math.Sqrt(2d * distance * acceleration * deceleration / (acceleration + deceleration));
|
||||
expectedSeconds = peakSpeed / acceleration + peakSpeed / deceleration;
|
||||
}
|
||||
|
||||
return expectedSeconds * 1000d;
|
||||
}
|
||||
|
||||
private string ValidateSetting()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Setting.AxisName))
|
||||
{
|
||||
return "轴名称不能为空";
|
||||
}
|
||||
|
||||
if (!AxisNames.Contains(Setting.AxisName))
|
||||
{
|
||||
return "请选择有效的轴名称";
|
||||
}
|
||||
|
||||
if (Setting.StepsCount <= 0)
|
||||
{
|
||||
return "步距次数必须大于0";
|
||||
}
|
||||
|
||||
if (Setting.WorkCount <= 0)
|
||||
{
|
||||
return "循环次数必须大于0";
|
||||
}
|
||||
|
||||
if (Math.Abs(Setting.Steps) <= 0d)
|
||||
{
|
||||
return "步距必须非0";
|
||||
}
|
||||
|
||||
if (Setting.JumpPos < 0d)
|
||||
{
|
||||
return "跃程不能小于0";
|
||||
}
|
||||
|
||||
if (Setting.Speed <= 0d)
|
||||
{
|
||||
return "速度必须大于0";
|
||||
}
|
||||
|
||||
if (Setting.DwellTime < 0d)
|
||||
{
|
||||
return "延时时间不能小于0";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private string BuildStartLogMessage()
|
||||
{
|
||||
return $"激光补偿启动:轴={Setting.AxisName},StartPos={Setting.StartPos:F4},Steps={Setting.Steps:F4},StepsCount={Setting.StepsCount},JumpPos={Setting.JumpPos:F4},WorkCount={Setting.WorkCount},Speed={Setting.Speed:F4},DwellTime={Setting.DwellTime:F3}s";
|
||||
}
|
||||
|
||||
private string BuildFinishLogMessage(string state)
|
||||
{
|
||||
return $"激光补偿结束:状态={state},轴={Setting.AxisName},已执行循环={CurrentLoopIndex},最后点位={CurrentPointIndex},最后目标={CurrentTargetPosition:F4}";
|
||||
}
|
||||
|
||||
private IEnumerable<string> BuildAxisNames()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
GetAxisName(_hardwareManager?.Axis_PHS_X1, MainShell.Hardware.AxisName.Axis_PHS_X1),
|
||||
GetAxisName(_hardwareManager?.Axis_PHS_X2, MainShell.Hardware.AxisName.Axis_PHS_X2),
|
||||
GetAxisName(_hardwareManager?.Axis_PHS_Y1, MainShell.Hardware.AxisName.Axis_PHS_Y1),
|
||||
GetAxisName(_hardwareManager?.Axis_WS_X3, MainShell.Hardware.AxisName.Axis_WS_X3),
|
||||
GetAxisName(_hardwareManager?.Axis_Stage_Y3, MainShell.Hardware.AxisName.Axis_Stage_Y3),
|
||||
GetAxisName(_hardwareManager?.Axis_WS_R, MainShell.Hardware.AxisName.Axis_WS_R),
|
||||
}.Where(x => !string.IsNullOrWhiteSpace(x)).Distinct().ToArray();
|
||||
}
|
||||
|
||||
private static string GetAxisName(IAxis axis, string fallbackName)
|
||||
{
|
||||
if (axis == null || string.IsNullOrWhiteSpace(axis.Name))
|
||||
{
|
||||
return fallbackName;
|
||||
}
|
||||
|
||||
return axis.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Models;
|
||||
using MainShell.Recipe.Models;
|
||||
using MaxwellFramework.Core.Common;
|
||||
using MaxwellFramework.Core.Interfaces;
|
||||
using MwFramework.ManagerService;
|
||||
using MXJM.Parameter.Maintance;
|
||||
using Stylet;
|
||||
using StyletIoC;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class NeedleBaseViewModel : CameraBaseViewModel, IPage
|
||||
{
|
||||
private readonly Dictionary<string, Screen> _screenDics = new Dictionary<string, Screen>();
|
||||
|
||||
private const string NEEDLE_CAMERA_CALIB = "针尖相机校准";
|
||||
private const string CAMERA_ACCURACY_CALIB = "针印检测";
|
||||
private const string NEEDLECALIB = "针尖对刀检查";
|
||||
|
||||
private Screen _currentScreen;
|
||||
public Screen CurrentScreen
|
||||
{
|
||||
get => _currentScreen;
|
||||
set { SetAndNotify(ref _currentScreen, value); }
|
||||
}
|
||||
|
||||
private ObservableCollection<string> _navigationItems = new ObservableCollection<string>();
|
||||
public ObservableCollection<string> NavigationItems
|
||||
{
|
||||
get => _navigationItems;
|
||||
set
|
||||
{
|
||||
_navigationItems = value;
|
||||
OnPropertyChanged(nameof(NavigationItems));
|
||||
}
|
||||
}
|
||||
|
||||
private string _selectedItem;
|
||||
public string SelectedItem
|
||||
{
|
||||
get => _selectedItem;
|
||||
set
|
||||
{
|
||||
_selectedItem = value;
|
||||
OnPropertyChanged(nameof(SelectedItem));
|
||||
// 当选择项改变时,更新当前ViewModel
|
||||
if (_selectedItem != null)
|
||||
{
|
||||
CurrentScreen = _screenDics[value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private NeedleCaliViewModel _needleCaliViewModel;
|
||||
[Inject]
|
||||
public NeedleCaliViewModel NeedleCaliViewModel
|
||||
{
|
||||
get { return _needleCaliViewModel; }
|
||||
set { _needleCaliViewModel = value; }
|
||||
}
|
||||
|
||||
private NeedleCameraPrintViewModel _needleCameraPrintViewModel;
|
||||
[Inject]
|
||||
public NeedleCameraPrintViewModel NeedleCameraPrintViewModel
|
||||
{
|
||||
get { return _needleCameraPrintViewModel; }
|
||||
set { _needleCameraPrintViewModel = value; }
|
||||
}
|
||||
|
||||
private CameraAccuracyCalibrationViewModel _cameraAccuracyCalibrationViewModel;
|
||||
[Inject]
|
||||
public CameraAccuracyCalibrationViewModel CameraAccuracyCalibrationViewModel
|
||||
{
|
||||
get { return _cameraAccuracyCalibrationViewModel; }
|
||||
set { _cameraAccuracyCalibrationViewModel = value; }
|
||||
}
|
||||
private HardwareManager _hardwareManager;
|
||||
public NeedleBaseViewModel(HardwareManager hardwareManager)
|
||||
{
|
||||
_hardwareManager = hardwareManager ?? throw new ArgumentNullException(nameof(hardwareManager));
|
||||
_cameraAxisViewModel = IoC.Get<Common.Display.ViewModel.CameraAxisViewModel>();
|
||||
_cameraAxisViewModel.CameraAxisDevices.HardwareDeviceList = hardwareManager.CameraAxisManager.TopCameraAxisDevices;
|
||||
InitNavigationItems();
|
||||
}
|
||||
|
||||
protected override void OnViewLoaded()
|
||||
{
|
||||
base.OnViewLoaded();
|
||||
if (_screenDics.Count == 0)
|
||||
{
|
||||
InitScreenDics();
|
||||
}
|
||||
if (SelectedItem == null)
|
||||
SelectedItem = NavigationItems[0];
|
||||
}
|
||||
|
||||
public void InitNavigationItems()
|
||||
{
|
||||
NavigationItems.Add(NEEDLE_CAMERA_CALIB);
|
||||
NavigationItems.Add(CAMERA_ACCURACY_CALIB);
|
||||
NavigationItems.Add(NEEDLECALIB);
|
||||
}
|
||||
|
||||
public void InitScreenDics()
|
||||
{
|
||||
_screenDics.Add(NEEDLE_CAMERA_CALIB, NeedleCameraPrintViewModel);
|
||||
_screenDics.Add(NEEDLECALIB, NeedleCaliViewModel);
|
||||
_screenDics.Add(CAMERA_ACCURACY_CALIB, CameraAccuracyCalibrationViewModel);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,454 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.DeviceMaintance.Model;
|
||||
using MainShell.EventArgsFolder;
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Models;
|
||||
using MainShell.Motion;
|
||||
using MainShell.Parameter;
|
||||
using MainShell.Process;
|
||||
using MainShell.Recipe.Models;
|
||||
using MaxwellControl.Tools;
|
||||
using MaxwellFramework.Core.Interfaces;
|
||||
using MW.WorkFlow;
|
||||
using MwFramework.Device;
|
||||
using MwFramework.ManagerService;
|
||||
using MXJM.Parameter.Maintance;
|
||||
using Stylet;
|
||||
using StyletIoC;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class NeedleCaliViewModel : DeviceMaintanceBaseViewModel, IPage, IHandle<NeedleZCalibrationResultEventArgs>
|
||||
{
|
||||
private const string CalibrationWorkflowName = "NeedleZCalibration";
|
||||
|
||||
private readonly IParameterManager _parameterManager;
|
||||
private readonly IParamList _paramList;
|
||||
private readonly SafeAxisMotion _safeAxisMotion;
|
||||
private readonly StagePlatformMotionService _stagePlatformMotionService;
|
||||
private readonly HardwareManager _hardwareManager;
|
||||
private readonly IDeviceIoMonitorService _deviceIoMonitorService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly WorkflowRunner _workflowRunner;
|
||||
private readonly NeedleZCalibrationService _needleZCalibrationService;
|
||||
private ParameterHelper _parameterHelper = new ParameterHelper();
|
||||
private NeedleCalibrationSetting _needleCalibrationSetting;
|
||||
private NeedleZCalibrationItem _needleZCalibrationItem;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
private bool _uiEnable = true;
|
||||
private bool _autoRaiseZ1 = true;
|
||||
private bool _isEnabledNeedleCalibrationControl = true;
|
||||
private NeedleTouchRecord _selectedRecord;
|
||||
|
||||
public NeedleCaliViewModel(IParameterManager parameterManager, SafeAxisMotion safeAxisMotion,
|
||||
StagePlatformMotionService stagePlatformMotionService, HardwareManager hardwareManager,
|
||||
IDeviceIoMonitorService deviceIoMonitorService, IEventAggregator eventAggregator,
|
||||
WorkflowRunner workflowRunner, NeedleZCalibrationService needleZCalibrationService)
|
||||
{
|
||||
_parameterManager = parameterManager;
|
||||
_paramList = parameterManager as IParamList;
|
||||
_safeAxisMotion = safeAxisMotion;
|
||||
_stagePlatformMotionService = stagePlatformMotionService;
|
||||
_hardwareManager = hardwareManager;
|
||||
_deviceIoMonitorService = deviceIoMonitorService;
|
||||
_eventAggregator = eventAggregator;
|
||||
_workflowRunner = workflowRunner;
|
||||
_needleZCalibrationService = needleZCalibrationService;
|
||||
_eventAggregator?.Subscribe(this);
|
||||
}
|
||||
|
||||
public string Name { get; set; } = "NeedleCaliMaint";
|
||||
|
||||
public ParameterHelper ParameterHelper
|
||||
{
|
||||
get => _parameterHelper;
|
||||
set => SetAndNotify(ref _parameterHelper, value);
|
||||
}
|
||||
|
||||
public NeedleCalibrationSetting NeedleCalibrationSetting
|
||||
{
|
||||
get => _needleCalibrationSetting;
|
||||
set => SetAndNotify(ref _needleCalibrationSetting, value);
|
||||
}
|
||||
|
||||
public NeedleZCalibrationItem NeedleZCalibrationItem
|
||||
{
|
||||
get => _needleZCalibrationItem;
|
||||
set => SetAndNotify(ref _needleZCalibrationItem, value);
|
||||
}
|
||||
|
||||
public bool UiEnable
|
||||
{
|
||||
get => _uiEnable;
|
||||
set
|
||||
{
|
||||
if (SetAndNotify(ref _uiEnable, value))
|
||||
{
|
||||
OnUiStateChanged(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutoRaiseZ1
|
||||
{
|
||||
get => _autoRaiseZ1;
|
||||
set => SetAndNotify(ref _autoRaiseZ1, value);
|
||||
}
|
||||
|
||||
public bool IsEnabledNeedleCalibrationControl
|
||||
{
|
||||
get => _isEnabledNeedleCalibrationControl;
|
||||
set => SetAndNotify(ref _isEnabledNeedleCalibrationControl, value);
|
||||
}
|
||||
|
||||
public NeedleTouchRecord SelectedRecord
|
||||
{
|
||||
get => _selectedRecord;
|
||||
set => SetAndNotify(ref _selectedRecord, value);
|
||||
}
|
||||
|
||||
protected override void OnViewLoaded()
|
||||
{
|
||||
base.OnViewLoaded();
|
||||
LoadParameters();
|
||||
}
|
||||
|
||||
protected override void OnClose()
|
||||
{
|
||||
_eventAggregator?.Unsubscribe(this);
|
||||
base.OnClose();
|
||||
}
|
||||
|
||||
public void Handle(NeedleZCalibrationResultEventArgs message)
|
||||
{
|
||||
if (message == null || NeedleZCalibrationItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
EnsureRecordCollection();
|
||||
int index = NeedleZCalibrationItem.NeedleTouchRecords.Count + 1;
|
||||
NeedleZCalibrationItem.NeedleTouchHeight = message.Result;
|
||||
NeedleZCalibrationItem.NeedleTouchRecords.Add(new NeedleTouchRecord
|
||||
{
|
||||
CurrentCount = index,
|
||||
Height = message.Result,
|
||||
});
|
||||
SelectedRecord = NeedleZCalibrationItem.NeedleTouchRecords.LastOrDefault();
|
||||
RefreshStatistics();
|
||||
});
|
||||
}
|
||||
|
||||
public void MoveCzCurrentLocation()
|
||||
{
|
||||
ExecuteMotion(() =>
|
||||
{
|
||||
if (NeedleZCalibrationItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_safeAxisMotion.MoveAbs(_hardwareManager.Axis_SZ, NeedleZCalibrationItem.CZHeight);
|
||||
_stagePlatformMotionService.MoveFlat(NeedleZCalibrationItem.StageHeight);
|
||||
});
|
||||
}
|
||||
|
||||
public void ReadGantry2CurrentLocation()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
if (NeedleZCalibrationItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NeedleZCalibrationItem.Gantry2AvoidPositionX = GetAxisPosition(_hardwareManager.Axis_X2);
|
||||
NeedleZCalibrationItem.Gantry2AvoidPositionY = GetAxisPosition(_hardwareManager.Axis_Y2);
|
||||
});
|
||||
}
|
||||
|
||||
public void MoveGantry2ToCurrentLocation()
|
||||
{
|
||||
ExecuteMotion(() =>
|
||||
{
|
||||
if (NeedleZCalibrationItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_safeAxisMotion.MoveAbs(_hardwareManager.Axis_X2, NeedleZCalibrationItem.Gantry2AvoidPositionX);
|
||||
_safeAxisMotion.MoveAbs(_hardwareManager.Axis_Y2, NeedleZCalibrationItem.Gantry2AvoidPositionY);
|
||||
});
|
||||
}
|
||||
|
||||
public void ReadSupportPinCurrentLocation()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
if (NeedleZCalibrationItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NeedleZCalibrationItem.SupportPinPositionX = GetAxisPosition(_hardwareManager.Axis_X1);
|
||||
NeedleZCalibrationItem.SupportPinPositionY = GetAxisPosition(_hardwareManager.Axis_Y1);
|
||||
});
|
||||
}
|
||||
|
||||
public void MoveSupportPinToCurrentLocation()
|
||||
{
|
||||
ExecuteMotion(() =>
|
||||
{
|
||||
if (NeedleZCalibrationItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_safeAxisMotion.MoveAbs(_hardwareManager.Axis_X1, NeedleZCalibrationItem.SupportPinPositionX);
|
||||
_safeAxisMotion.MoveAbs(_hardwareManager.Axis_Y1, NeedleZCalibrationItem.SupportPinPositionY);
|
||||
});
|
||||
}
|
||||
|
||||
public void SetBaseHeight()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
if (NeedleZCalibrationItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NeedleZCalibrationItem.NeedleTouchHeightBase = NeedleZCalibrationItem.CurrentNeedleTouchHeight;
|
||||
RefreshStatistics();
|
||||
});
|
||||
}
|
||||
|
||||
public async void StartSingleZ1CalibrationAsync()
|
||||
{
|
||||
await ExecuteCalibrationAsync(1, false);
|
||||
}
|
||||
|
||||
public void UseCurrentZ1Height()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
if (NeedleZCalibrationItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NeedleZCalibrationItem.CurrentNeedleTouchHeight = NeedleZCalibrationItem.NeedleTouchHeightAve + NeedleZCalibrationItem.KnifeOffset;
|
||||
RefreshStatistics();
|
||||
SaveParameterInternal(true);
|
||||
});
|
||||
}
|
||||
|
||||
public async void StartCalibrationAsync()
|
||||
{
|
||||
await ExecuteCalibrationAsync(Math.Max(1, NeedleZCalibrationItem != null ? NeedleZCalibrationItem.NeedleTouchCount : 1), true);
|
||||
}
|
||||
|
||||
public async void StopCalibrationAsync()
|
||||
{
|
||||
_cancellationTokenSource?.Cancel();
|
||||
if (_workflowRunner != null && _workflowRunner.IsRunning)
|
||||
{
|
||||
await _workflowRunner.StopAsync();
|
||||
}
|
||||
|
||||
_safeAxisMotion.Stop(
|
||||
_hardwareManager.Axis_X1,
|
||||
_hardwareManager.Axis_X2,
|
||||
_hardwareManager.Axis_Y1,
|
||||
_hardwareManager.Axis_Y2,
|
||||
_hardwareManager.Axis_Z1,
|
||||
_hardwareManager.Axis_SZ,
|
||||
_hardwareManager.Axis_Stage_Z7,
|
||||
_hardwareManager.Axis_Stage_Z8,
|
||||
_hardwareManager.Axis_Stage_Z9);
|
||||
|
||||
UiEnable = true;
|
||||
}
|
||||
|
||||
public void SaveCalibration()
|
||||
{
|
||||
CommonUti.RunOnUi(() => SaveParameterInternal(true));
|
||||
}
|
||||
|
||||
private async Task ExecuteCalibrationAsync(int touchCount, bool clearRecords)
|
||||
{
|
||||
if (NeedleZCalibrationItem == null)
|
||||
{
|
||||
LoadParameters();
|
||||
}
|
||||
|
||||
if (NeedleZCalibrationItem == null)
|
||||
{
|
||||
LocalizedMessageBox.Show(MessageKey.NeedleCalibrationLoadFailed, MessageKey.TitleError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (touchCount <= 0)
|
||||
{
|
||||
LocalizedMessageBox.Show(MessageKey.NeedleCalibrationTouchCountMustGreaterThanZero, MessageKey.TitleWarning);
|
||||
return;
|
||||
}
|
||||
|
||||
InitCancelToken();
|
||||
if (clearRecords)
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
EnsureRecordCollection();
|
||||
NeedleZCalibrationItem.NeedleTouchRecords.Clear();
|
||||
NeedleZCalibrationItem.NeedleTouchHeight = 0;
|
||||
NeedleZCalibrationItem.NeedleTouchHeightAve = 0;
|
||||
NeedleZCalibrationItem.CurrentNeedleTouchHeight = 0;
|
||||
NeedleZCalibrationItem.NeedleTouchOffset = 0;
|
||||
});
|
||||
}
|
||||
|
||||
UiEnable = false;
|
||||
try
|
||||
{
|
||||
WorkflowContext context = new WorkflowContext();
|
||||
NeedleZCalibrationWorkflowData workflowData = new NeedleZCalibrationWorkflowData(
|
||||
CalibrationWorkflowName,
|
||||
touchCount,
|
||||
AutoRaiseZ1,
|
||||
_cancellationTokenSource.Token,
|
||||
_eventAggregator,
|
||||
_hardwareManager,
|
||||
_safeAxisMotion,
|
||||
_parameterManager,
|
||||
_deviceIoMonitorService);
|
||||
context.SetData(WorkflowContextKeys.WorkflowName, workflowData.WorkflowName);
|
||||
context.SetData(WorkflowContextKeys.NeedleZCalibrationWorkflowData, workflowData);
|
||||
|
||||
NeedleZCalibrationActivity activity = new NeedleZCalibrationActivity(_needleZCalibrationService);
|
||||
WorkflowRunCompletedEventArgs result = await _workflowRunner.RunActivityWithResultAsync(activity, context);
|
||||
switch (result != null ? result.FinalState : WorkflowState.Faulted)
|
||||
{
|
||||
case WorkflowState.Completed:
|
||||
RefreshStatistics();
|
||||
LocalizedMessageBox.Show(MessageKey.NeedleCalibrationCompleted, MessageKey.TitleInfo);
|
||||
break;
|
||||
case WorkflowState.Canceled:
|
||||
LocalizedMessageBox.Show(MessageKey.NeedleCalibrationStopped, MessageKey.TitleWarning);
|
||||
break;
|
||||
case WorkflowState.Faulted:
|
||||
string failureMessage = string.IsNullOrWhiteSpace(result != null ? result.FailureMessage : null)
|
||||
? (result != null ? result.Error : null)
|
||||
: result.FailureMessage;
|
||||
if (string.IsNullOrWhiteSpace(failureMessage))
|
||||
{
|
||||
LocalizedMessageBox.Show(MessageKey.ProcessFailed, MessageKey.TitleError);
|
||||
}
|
||||
else
|
||||
{
|
||||
LocalizedMessageBox.ShowFormat(MessageKey.ProcessFailedWithReason, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error, failureMessage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
LocalizedMessageBox.Show(MessageKey.NeedleCalibrationCanceled, MessageKey.TitleWarning);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LocalizedMessageBox.ShowFormat(MessageKey.ProcessFailedWithReason, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error, ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
UiEnable = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshStatistics()
|
||||
{
|
||||
if (NeedleZCalibrationItem == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ObservableCollection<NeedleTouchRecord> records = NeedleZCalibrationItem.NeedleTouchRecords;
|
||||
if (records == null || records.Count == 0)
|
||||
{
|
||||
NeedleZCalibrationItem.NeedleTouchHeightAve = 0;
|
||||
NeedleZCalibrationItem.CurrentNeedleTouchHeight = 0;
|
||||
NeedleZCalibrationItem.NeedleTouchOffset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
NeedleZCalibrationItem.NeedleTouchHeightAve = records.Average(x => x.Height);
|
||||
NeedleZCalibrationItem.CurrentNeedleTouchHeight = NeedleZCalibrationItem.NeedleTouchHeightAve + NeedleZCalibrationItem.KnifeOffset;
|
||||
NeedleZCalibrationItem.NeedleTouchOffset = NeedleZCalibrationItem.CurrentNeedleTouchHeight - NeedleZCalibrationItem.NeedleTouchHeightBase;
|
||||
}
|
||||
|
||||
private void SaveParameterInternal(bool showSuccessMessage)
|
||||
{
|
||||
NeedleCalibrationSetting?.Write();
|
||||
ParameterHelper?.RaiseValueAccept();
|
||||
if (showSuccessMessage)
|
||||
{
|
||||
LocalizedMessageBox.Show(MessageKey.CommonSaveSucceeded, MessageKey.TitleInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadParameters()
|
||||
{
|
||||
NeedleCalibrationSetting = _paramList?.GetParameter<NeedleCalibrationSetting>();
|
||||
NeedleZCalibrationItem = NeedleCalibrationSetting != null ? NeedleCalibrationSetting.NeedleZCalibrationItem : null;
|
||||
EnsureRecordCollection();
|
||||
}
|
||||
|
||||
private void EnsureRecordCollection()
|
||||
{
|
||||
if (NeedleZCalibrationItem != null && NeedleZCalibrationItem.NeedleTouchRecords == null)
|
||||
{
|
||||
NeedleZCalibrationItem.NeedleTouchRecords = new ObservableCollection<NeedleTouchRecord>();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitCancelToken()
|
||||
{
|
||||
_cancellationTokenSource?.Cancel();
|
||||
_cancellationTokenSource?.Dispose();
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
private double GetAxisPosition(IAxis axis)
|
||||
{
|
||||
if (axis == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return axis.State != null ? axis.State.ActualPos : axis.GetPositionImmediate();
|
||||
}
|
||||
|
||||
private void ExecuteMotion(Action action)
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
action?.Invoke();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LocalizedMessageBox.ShowFormat(MessageKey.ProcessFailedWithReason, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error, ex.Message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,536 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.DeviceMaintance.Model;
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Log;
|
||||
using MainShell.Models;
|
||||
using MainShell.Motion;
|
||||
using MainShell.Parameter;
|
||||
using MaxwellControl.Tools;
|
||||
using MaxwellFramework.Core.Interfaces;
|
||||
using MwFramework.ManagerService;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel
|
||||
{
|
||||
public class NeedleCameraPrintViewModel : DeviceMaintanceBaseViewModel
|
||||
{
|
||||
private NeedlePrintCalibrateSetting _needlePrintCalibrateSetting;
|
||||
private readonly IParamList _paramList;
|
||||
private readonly HardwareManager _device;
|
||||
private readonly SafeAxisMotion _safeMotion;
|
||||
private readonly GlobalParameterContext _globalParam;
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
private List<Point> _workPos;
|
||||
private readonly double _z1Speed = 70;
|
||||
private MaintanceRecord maintanceRecord;
|
||||
|
||||
private ParameterHelper _parameterHelper = new ParameterHelper();
|
||||
public ParameterHelper ParameterHelper
|
||||
{
|
||||
get
|
||||
{
|
||||
return _parameterHelper;
|
||||
}
|
||||
set
|
||||
{
|
||||
_parameterHelper = value;
|
||||
OnPropertyChanged(nameof(ParameterHelper));
|
||||
}
|
||||
}
|
||||
|
||||
private MPoint _cameraPoint;
|
||||
|
||||
public MPoint CameraPoint
|
||||
{
|
||||
get { return _cameraPoint; }
|
||||
set { SetAndNotify(ref _cameraPoint, value); }
|
||||
}
|
||||
|
||||
private MPoint _currentNeedlePoint;
|
||||
|
||||
public MPoint CurrentNeedlePoint
|
||||
{
|
||||
get { return _currentNeedlePoint; }
|
||||
set { SetAndNotify(ref _currentNeedlePoint, value); }
|
||||
}
|
||||
|
||||
private MPoint _currentNeedleOffsetPoint;
|
||||
|
||||
public MPoint CurrentNeedleOffsetPoint
|
||||
{
|
||||
get { return _currentNeedleOffsetPoint; }
|
||||
set { SetAndNotify(ref _currentNeedleOffsetPoint, value); }
|
||||
}
|
||||
|
||||
|
||||
private NeedlePrintCalibrateParameter _needlePrintCalibrateParameter;
|
||||
|
||||
public NeedlePrintCalibrateParameter NeedlePrintCalibrateParameter
|
||||
{
|
||||
get { return _needlePrintCalibrateParameter; }
|
||||
set { SetAndNotify(ref _needlePrintCalibrateParameter, value); }
|
||||
}
|
||||
|
||||
private bool _uiEnable = true;
|
||||
|
||||
public bool UiEnable
|
||||
{
|
||||
get { return _uiEnable; }
|
||||
set
|
||||
{
|
||||
if (SetAndNotify(ref _uiEnable, value))
|
||||
{
|
||||
OnUiStateChanged(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
public NeedleCameraPrintViewModel(IParameterManager parameterManager, GlobalParam globalParam, HardwareManager hardwareManager, SafeAxisMotion safeAxisMotion)
|
||||
{
|
||||
_currentNeedleOffsetPoint = new MPoint();
|
||||
CurrentNeedlePoint = new MPoint();
|
||||
_cameraPoint = new MPoint();
|
||||
_workPos = new List<Point>();
|
||||
_device = hardwareManager;
|
||||
_safeMotion = safeAxisMotion;
|
||||
_globalParam = globalParam;
|
||||
_paramList = parameterManager as IParamList;
|
||||
_needlePrintCalibrateSetting = _globalParam.NeedlePrintCalibrateSetting;
|
||||
_needlePrintCalibrateParameter = _needlePrintCalibrateSetting.NeedlePrintCalibrateParameter;
|
||||
SetSpeed(50);
|
||||
CalculteWorkPos();
|
||||
maintanceRecord = new MaintanceRecord()
|
||||
{
|
||||
DeviceId = LogManager.MachineID,
|
||||
MaintanceType = MaintanceType.针印验证,
|
||||
};
|
||||
}
|
||||
protected override void OnViewLoaded()
|
||||
{
|
||||
base.OnViewLoaded();
|
||||
NeedlePrintCalibrateParameter = _needlePrintCalibrateSetting.NeedlePrintCalibrateParameter;
|
||||
var needleCalibrationSetting = _globalParam.NeedleCalibrationSetting;
|
||||
CurrentNeedleOffsetPoint.X = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetX;
|
||||
CurrentNeedleOffsetPoint.Y = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetY;
|
||||
}
|
||||
public void SpeedChanged(object sender, EventArgs eventArgs)
|
||||
{
|
||||
if (sender is RadioButton radioButton)
|
||||
{
|
||||
if (radioButton.Tag != null)
|
||||
{
|
||||
var speed = Convert.ToInt32(radioButton.Tag);
|
||||
SetSpeed(speed);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
private void SetSpeed(double speed)
|
||||
{
|
||||
_safeMotion.SetAxisSpeed(_device.Axis_X1, speed);
|
||||
_safeMotion.SetAxisSpeed(_device.Axis_Y1, speed);
|
||||
_safeMotion.SetAxisSpeed(_device.Axis_X2, speed);
|
||||
_safeMotion.SetAxisSpeed(_device.Axis_Y2, speed);
|
||||
_safeMotion.SetAxisSpeed(_device.Axis_Z1, _z1Speed);
|
||||
}
|
||||
public void MoveToOrginPos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
MoveOrgin();
|
||||
});
|
||||
}
|
||||
public void TeachWSPos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
NeedlePrintCalibrateParameter.AvoidancePoint.X = _device.Axis_X2.GetPositionImmediate();
|
||||
NeedlePrintCalibrateParameter.AvoidancePoint.Y = _device.Axis_Y2.GetPositionImmediate();
|
||||
});
|
||||
}
|
||||
public void MoveToWsPos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
MoveAvoidancePos();
|
||||
});
|
||||
}
|
||||
public void TeachZ1Pos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
NeedlePrintCalibrateParameter.Z1WorkHeight = _device.Axis_Z1.GetPositionImmediate();
|
||||
});
|
||||
}
|
||||
public void MoveToZ1Pos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
MoveZ1Pos();
|
||||
});
|
||||
}
|
||||
public void TeachZ2Pos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
NeedlePrintCalibrateParameter.Z2WorkHeight = _device.Axis_Z2.GetPositionImmediate();
|
||||
});
|
||||
}
|
||||
public void MoveToZ2Pos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
MoveZ2Pos();
|
||||
});
|
||||
}
|
||||
public void TeachStartPos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
NeedlePrintCalibrateParameter.StartPoint.X = _device.Axis_X1.GetPositionImmediate();
|
||||
NeedlePrintCalibrateParameter.StartPoint.Y = _device.Axis_Y1.GetPositionImmediate();
|
||||
});
|
||||
}
|
||||
|
||||
public void MoveToStartPos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
_safeMotion.MoveAxis(new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_X11,
|
||||
Pos = NeedlePrintCalibrateParameter.StartPoint.PointX
|
||||
}, new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_Y11,
|
||||
Pos = NeedlePrintCalibrateParameter.StartPoint.PointY
|
||||
});
|
||||
});
|
||||
}
|
||||
public void TeachEndPos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
NeedlePrintCalibrateParameter.EndPoint.X = _device.Axis_X1.GetPositionImmediate();
|
||||
NeedlePrintCalibrateParameter.EndPoint.Y = _device.Axis_Y1.GetPositionImmediate();
|
||||
});
|
||||
}
|
||||
public void MoveToEndPos()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
_safeMotion.SafeMove(new MotionData
|
||||
{
|
||||
Name = "X1",
|
||||
TargetPosition = NeedlePrintCalibrateParameter.EndPoint.X
|
||||
}, new MotionData
|
||||
{
|
||||
Name = "y1",
|
||||
TargetPosition = NeedlePrintCalibrateParameter.EndPoint.Y
|
||||
});
|
||||
});
|
||||
}
|
||||
private void MoveOrgin()
|
||||
{
|
||||
_safeMotion.SafeMoveAxis(new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_CY,
|
||||
Pos = 0
|
||||
}, new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_CZ,
|
||||
Pos = 0
|
||||
});
|
||||
}
|
||||
private void MoveAvoidancePos()
|
||||
{
|
||||
_safeMotion.MoveAxis(new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_X21,
|
||||
Pos = NeedlePrintCalibrateParameter.AvoidancePoint.PointX
|
||||
}, new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_Y21,
|
||||
Pos = NeedlePrintCalibrateParameter.AvoidancePoint.PointY
|
||||
});
|
||||
}
|
||||
private void MoveZ1Pos()
|
||||
{
|
||||
_safeMotion.MoveAxis(new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_Z1,
|
||||
Pos = NeedlePrintCalibrateParameter.Z1WorkHeight
|
||||
});
|
||||
}
|
||||
private void MoveZ2Pos()
|
||||
{
|
||||
_safeMotion.MoveAxis(new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_Z2,
|
||||
Pos = NeedlePrintCalibrateParameter.Z2WorkHeight
|
||||
});
|
||||
}
|
||||
private void MoveAvoidanceAndWorkPos(Point workP)
|
||||
{
|
||||
_safeMotion.MoveAxis(new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_X21,
|
||||
Pos = NeedlePrintCalibrateParameter.AvoidancePoint.PointX
|
||||
}, new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_Y21,
|
||||
Pos = NeedlePrintCalibrateParameter.AvoidancePoint.PointY
|
||||
}, new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_X11,
|
||||
Pos = workP.X
|
||||
}, new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_Y11,
|
||||
Pos = workP.Y
|
||||
});
|
||||
}
|
||||
public void StartVerify()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
InitCancelToken();
|
||||
if (_workPos.Count == 0)
|
||||
{
|
||||
MaxwellControl.Controls.MessageBox.Show("无法计算有效的下扎点,请检查铜箔示教的起始点坐标");
|
||||
return;
|
||||
}
|
||||
if (_workPos.Count <= NeedlePrintCalibrateParameter.UsedNum)
|
||||
{
|
||||
MaxwellControl.Controls.MessageBox.Show("当前铜箔已用完,请确认是否需要更换");
|
||||
}
|
||||
IoC.Get<IProjectManager>().EnablePageAndDisableOther("刺晶头校正");
|
||||
VisionParData visionParData = new VisionParData
|
||||
{
|
||||
LightSourceBack = 0,
|
||||
LightSourceRingBlue = 255,
|
||||
LightSourcePointBlue = 255,
|
||||
LightSourcePointRed = 255,
|
||||
LightSourceRingRed = 255,
|
||||
};
|
||||
_safeMotion.MoveZToEscape();
|
||||
visionParData.SetLightData();
|
||||
CheckCancel();
|
||||
var workPoint = _workPos[NeedlePrintCalibrateParameter.UsedNum];
|
||||
CurrentNeedlePoint.PointX = workPoint.X;
|
||||
CurrentNeedlePoint.PointY = workPoint.Y;
|
||||
MoveOrgin();
|
||||
MoveAvoidanceAndWorkPos(workPoint);
|
||||
MoveZ1Pos();
|
||||
CheckCancel();
|
||||
Thread.Sleep(NeedlePrintCalibrateParameter.SleepTime);
|
||||
_safeMotion.Z1MoveToEscape();
|
||||
CheckCancel();
|
||||
var cameraPoint = IoC.Get<VisionOperation>().GetCameraRulerPointByRulerNeedle(new Point(_device.Axis_X11.GetPositionImmediate(), _device.Axis_Y11.GetPositionImmediate()));
|
||||
_safeMotion.SafeMoveAxis(new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_X11,
|
||||
Pos = cameraPoint.X
|
||||
}, new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_Y11,
|
||||
Pos = cameraPoint.Y
|
||||
});
|
||||
MoveZ2Pos();
|
||||
NeedlePrintCalibrateParameter.UsedNum++;
|
||||
_needlePrintCalibrateSetting.Write();
|
||||
}, exceptionHandler: ex =>
|
||||
{
|
||||
_safeMotion.MoveZToEscape();
|
||||
CommonUti.ShowMessageBox(ex);
|
||||
}, begainAction: () =>
|
||||
{
|
||||
UiEnable = false;
|
||||
}, afterAction: () =>
|
||||
{
|
||||
UiEnable = true;
|
||||
IoC.Get<IProjectManager>().SwitchState();
|
||||
});
|
||||
}
|
||||
|
||||
private void InitCancelToken()
|
||||
{
|
||||
if (_cancellationTokenSource != null)
|
||||
{
|
||||
_cancellationTokenSource.Cancel();
|
||||
_cancellationTokenSource.Dispose();
|
||||
}
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
}
|
||||
|
||||
private void CheckCancel()
|
||||
{
|
||||
_cancellationTokenSource.Token.ThrowIfCancellationRequested();
|
||||
}
|
||||
public void StopVerify()
|
||||
{
|
||||
_cancellationTokenSource?.Cancel();
|
||||
IoC.Get<CancelSourceManager>().CancelMotionAndCheck();
|
||||
IoC.Get<GlobalDeviceService>().StopMainAxis();
|
||||
}
|
||||
|
||||
public void void NeedleAlignment()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
var needlePoint = IoC.Get<VisionOperation>().GetNeedleRulerPointByRulerCamera(new Point(_device.Axis_X11.GetPositionImmediate(), _device.Axis_Y11.GetPositionImmediate()));
|
||||
_safeMotion.SafeMoveAxis(new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_X11,
|
||||
Pos = needlePoint.X
|
||||
}, new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_Y11,
|
||||
Pos = needlePoint.Y
|
||||
});
|
||||
});
|
||||
}
|
||||
public void void CameraAlignment()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
var cameraPoint = IoC.Get<VisionOperation>().GetCameraRulerPointByRulerNeedle(new Point(_device.Axis_X11.GetPositionImmediate(), _device.Axis_Y11.GetPositionImmediate()));
|
||||
_safeMotion.SafeMoveAxis(new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_X11,
|
||||
Pos = cameraPoint.X
|
||||
}, new AxisPos
|
||||
{
|
||||
Axis = _device.Axis_Y11,
|
||||
Pos = cameraPoint.Y
|
||||
});
|
||||
});
|
||||
}
|
||||
public void SaveParam()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
CalculteWorkPos();
|
||||
if (_workPos.Count == 0)
|
||||
{
|
||||
MaxwellControl.Controls.MessageBox.Show("无法计算有效的下扎点,请检查铜箔示教的起始点坐标");
|
||||
return;
|
||||
}
|
||||
_needlePrintCalibrateSetting.Write();
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
ParameterHelper.RaiseValueAccept();
|
||||
});
|
||||
MaxwellControl.Controls.MessageBox.Show("操作成功");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void ResetRecord()
|
||||
{
|
||||
NeedlePrintCalibrateParameter.UsedNum = 0;
|
||||
SaveParam();
|
||||
}
|
||||
|
||||
public void TeachCameraPos()
|
||||
{
|
||||
CameraPoint.PointX = _device.Axis_X11.GetPositionImmediate();
|
||||
CameraPoint.PointY = _device.Axis_Y11.GetPositionImmediate();
|
||||
}
|
||||
public void CalculateOffset()
|
||||
{
|
||||
CommonUti.RunOnUi(() =>
|
||||
{
|
||||
if (CameraPoint.PointX == 0 || CameraPoint.PointY == 0 || CurrentNeedlePoint.PointX == 0 || CurrentNeedlePoint.PointY == 0)
|
||||
{
|
||||
MaxwellControl.Controls.MessageBox.Show("请先示教相机位置和针尖位置");
|
||||
return;
|
||||
}
|
||||
List<Point> cameraRealPointList = new List<Point>();
|
||||
List<Point> needleRealPointList = new List<Point>();
|
||||
VisionOperation visionOperation = IoC.Get<VisionOperation>();
|
||||
|
||||
Point cameraPointReal = visionOperation.GetRealByRuler(_device.Camera_Extend.Id, new Point(CameraPoint.PointX, CameraPoint.PointY));
|
||||
Point needlePointReal = visionOperation.GetRealByRuler(_device.Camera_Extend.Id, new Point(CurrentNeedlePoint.PointX, CurrentNeedlePoint.PointY));
|
||||
var needleCalibrationSetting = _paramList.GetParameter<NeedleCalibrationSetting>();
|
||||
needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetX = needlePointReal.X - cameraPointReal.X;
|
||||
needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetY = needlePointReal.Y - cameraPointReal.Y;
|
||||
var offsetX = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetX - needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetX;
|
||||
var offsetY = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetY - needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetY;
|
||||
if (Math.Abs(offsetY) >= 2 || Math.Abs(offsetX) > 2.5)
|
||||
{
|
||||
MaxwellControl.Controls.MessageBox.Show("当前相机与针尖偏差过大,请重新校准!");
|
||||
return;
|
||||
}
|
||||
needleCalibrationSetting.NeedleXYCalibrationItem.OffsetX = needleCalibrationSetting.NeedleXYCalibrationItem.CompensateX + needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetX;
|
||||
needleCalibrationSetting.NeedleXYCalibrationItem.OffsetY = needleCalibrationSetting.NeedleXYCalibrationItem.CompensateY + needleCalibrationSetting.NeedleXYCalibrationItem.InitialOffsetY;
|
||||
|
||||
CurrentNeedleOffsetPoint.PointX = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetX;
|
||||
CurrentNeedleOffsetPoint.PointY = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetY;
|
||||
|
||||
EquipmentParaSysSetting equipmentParaSysSetting = _paramList.GetParameter<EquipmentParaSysSetting>();
|
||||
equipmentParaSysSetting.SafeParaSysItem.NeedleCameraOffsetX = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetX;
|
||||
equipmentParaSysSetting.SafeParaSysItem.NeedleCameraOffsetY = needleCalibrationSetting.NeedleXYCalibrationItem.OffsetY;
|
||||
equipmentParaSysSetting.Write();
|
||||
needleCalibrationSetting.Write();
|
||||
maintanceRecord.WriteToFile($"当前相机与针尖与上次偏差 X:{offsetX} Y:{offsetY}");
|
||||
MaxwellControl.Controls.MessageBox.Show("操作成功");
|
||||
|
||||
});
|
||||
}
|
||||
private void CalculteWorkPos()
|
||||
{
|
||||
_workPos.Clear();
|
||||
var startPoint = new Point(NeedlePrintCalibrateParameter.StartPoint.X, NeedlePrintCalibrateParameter.StartPoint.PointY);
|
||||
var width = NeedlePrintCalibrateParameter.EndPoint.X - NeedlePrintCalibrateParameter.StartPoint.X;
|
||||
var height = NeedlePrintCalibrateParameter.EndPoint.Y - NeedlePrintCalibrateParameter.StartPoint.Y;
|
||||
var xscale = width > 0 ? 1 : -1;
|
||||
var yscale = height > 0 ? 1 : -1;
|
||||
var xcount = Math.Floor(Math.Abs(width) / NeedlePrintCalibrateParameter.Xpitch);
|
||||
var ycount = Math.Floor(Math.Abs(height) / NeedlePrintCalibrateParameter.Ypitch);
|
||||
for (int i = 0; i < ycount; i++)
|
||||
{
|
||||
for (int j = 0; j < xcount; j++)
|
||||
{
|
||||
var cameraPoint = new Point
|
||||
{
|
||||
X = startPoint.X + xscale * i * NeedlePrintCalibrateParameter.Xpitch,
|
||||
Y = startPoint.Y + yscale * j * NeedlePrintCalibrateParameter.Ypitch,
|
||||
};
|
||||
|
||||
var needlePoint = IoC.Get<VisionOperation>().GetNeedleRulerPointByRulerCamera(cameraPoint);
|
||||
_workPos.Add(needlePoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
private bool CheckPointInRange(Point point)
|
||||
{
|
||||
return IsPointInRange(NeedlePrintCalibrateParameter.StartPoint, NeedlePrintCalibrateParameter.EndPoint, point);
|
||||
}
|
||||
|
||||
bool IsPointInRange(MPoint p1, MPoint p2, Point current)
|
||||
{
|
||||
// 计算最小和最大 X 和 Y 值
|
||||
double minX = Math.Min(p1.X, p2.X);
|
||||
double maxX = Math.Max(p1.X, p2.X);
|
||||
double minY = Math.Min(p1.Y, p2.Y);
|
||||
double maxY = Math.Max(p1.Y, p2.Y);
|
||||
|
||||
// 检查待判断的点是否在范围内
|
||||
return (current.X >= minX && current.X <= maxX) && (current.Y >= minY && current.Y <= maxY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using MainShell.Manual.ViewModel.State;
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel.State
|
||||
{
|
||||
public class CylinderPageState : PropertyChangedBase
|
||||
{
|
||||
private DateTime _lastActionTime = DateTime.MinValue;
|
||||
private string _lastActionMessage = "等待气缸控制操作";
|
||||
|
||||
public DateTime LastActionTime
|
||||
{
|
||||
get { return _lastActionTime; }
|
||||
set { SetAndNotify(ref _lastActionTime, value); }
|
||||
}
|
||||
|
||||
public string LastActionMessage
|
||||
{
|
||||
get { return _lastActionMessage; }
|
||||
set { SetAndNotify(ref _lastActionMessage, value); }
|
||||
}
|
||||
|
||||
public ObservableCollection<CylinderItemState> Cylinders { get; } = new ObservableCollection<CylinderItemState>();
|
||||
}
|
||||
|
||||
public class CylinderItemState : PropertyChangedBase
|
||||
{
|
||||
private bool _isBusy;
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Module { get; set; }
|
||||
public string ControlTypeText { get; set; }
|
||||
|
||||
public bool IsBusy
|
||||
{
|
||||
get { return _isBusy; }
|
||||
set { SetAndNotify(ref _isBusy, value); }
|
||||
}
|
||||
|
||||
public ObservableCollection<CylinderSignalState> OutputSignals { get; } = new ObservableCollection<CylinderSignalState>();
|
||||
public ObservableCollection<CylinderSignalState> FeedbackSignals { get; } = new ObservableCollection<CylinderSignalState>();
|
||||
|
||||
public ICommand ExtendCommand { get; set; }
|
||||
public ICommand RetractCommand { get; set; }
|
||||
}
|
||||
|
||||
public class CylinderSignalState : PropertyChangedBase
|
||||
{
|
||||
private bool _isOn;
|
||||
|
||||
public string PointReference { get; set; }
|
||||
public string PointKey { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string LineNo { get; set; }
|
||||
public bool IsOutput { get; set; }
|
||||
|
||||
public string IoNameText
|
||||
{
|
||||
get { return string.IsNullOrWhiteSpace(PointReference) ? string.Empty : "IO Name:" + PointReference; }
|
||||
}
|
||||
|
||||
public bool IsOn
|
||||
{
|
||||
get { return _isOn; }
|
||||
set
|
||||
{
|
||||
if (SetAndNotify(ref _isOn, value))
|
||||
{
|
||||
OnPropertyChanged(nameof(StateText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string StateText
|
||||
{
|
||||
get { return IsOn ? "ON" : "OFF"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
using Stylet;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace MainShell.DeviceMaintance.ViewModel.State
|
||||
{
|
||||
public class DeviceIoPageState : PropertyChangedBase
|
||||
{
|
||||
private DateTime _lastRefreshTime = DateTime.MinValue;
|
||||
private DateTime _lastWriteTime = DateTime.MinValue;
|
||||
private bool _isOnline;
|
||||
private bool _isWriteSuccess;
|
||||
private string _lastWriteMessage = "等待写入操作";
|
||||
|
||||
public DateTime LastRefreshTime
|
||||
{
|
||||
get { return _lastRefreshTime; }
|
||||
set { SetAndNotify(ref _lastRefreshTime, value); }
|
||||
}
|
||||
|
||||
public DateTime LastWriteTime
|
||||
{
|
||||
get { return _lastWriteTime; }
|
||||
set { SetAndNotify(ref _lastWriteTime, value); }
|
||||
}
|
||||
|
||||
public bool IsOnline
|
||||
{
|
||||
get { return _isOnline; }
|
||||
set
|
||||
{
|
||||
if (SetAndNotify(ref _isOnline, value))
|
||||
{
|
||||
OnPropertyChanged(nameof(OnlineText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsWriteSuccess
|
||||
{
|
||||
get { return _isWriteSuccess; }
|
||||
set { SetAndNotify(ref _isWriteSuccess, value); }
|
||||
}
|
||||
|
||||
public string LastWriteMessage
|
||||
{
|
||||
get { return _lastWriteMessage; }
|
||||
set { SetAndNotify(ref _lastWriteMessage, value); }
|
||||
}
|
||||
|
||||
public string OnlineText
|
||||
{
|
||||
get { return IsOnline ? "在线" : "离线/模拟"; }
|
||||
}
|
||||
|
||||
public ObservableCollection<DeviceIoModuleState> Modules { get; } = new ObservableCollection<DeviceIoModuleState>();
|
||||
}
|
||||
|
||||
public class DeviceIoModuleState : PropertyChangedBase
|
||||
{
|
||||
private string _name;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set { SetAndNotify(ref _name, value); }
|
||||
}
|
||||
|
||||
public ObservableCollection<DeviceIoPointItemState> InputPoints { get; } = new ObservableCollection<DeviceIoPointItemState>();
|
||||
public ObservableCollection<DeviceIoPointItemState> OutputPoints { get; } = new ObservableCollection<DeviceIoPointItemState>();
|
||||
|
||||
public bool HasInputs
|
||||
{
|
||||
get { return InputPoints.Count > 0; }
|
||||
}
|
||||
|
||||
public bool HasOutputs
|
||||
{
|
||||
get { return OutputPoints.Count > 0; }
|
||||
}
|
||||
}
|
||||
|
||||
public class DeviceIoPointItemState : PropertyChangedBase
|
||||
{
|
||||
private bool _isOn;
|
||||
private bool _canWrite;
|
||||
|
||||
public int Id { get; set; }
|
||||
public string PointKey { get; set; }
|
||||
public string Module { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int StationNo { get; set; }
|
||||
public string LineNo { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool IsOutput { get; set; }
|
||||
public bool IsInverse { get; set; }
|
||||
|
||||
public bool IsOn
|
||||
{
|
||||
get { return _isOn; }
|
||||
set
|
||||
{
|
||||
if (SetAndNotify(ref _isOn, value))
|
||||
{
|
||||
OnPropertyChanged(nameof(StateText));
|
||||
OnPropertyChanged(nameof(ToggleText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanWrite
|
||||
{
|
||||
get { return _canWrite; }
|
||||
set { SetAndNotify(ref _canWrite, value); }
|
||||
}
|
||||
|
||||
public string StateText
|
||||
{
|
||||
get { return IsOn ? "ON" : "OFF"; }
|
||||
}
|
||||
|
||||
public string ToggleText
|
||||
{
|
||||
get { return IsOn ? "ON" : "OFF"; }
|
||||
}
|
||||
|
||||
public ICommand ToggleCommand { get; set; }
|
||||
}
|
||||
|
||||
public class ActionCommand : ICommand
|
||||
{
|
||||
private readonly Action _execute;
|
||||
private readonly Func<bool> _canExecute;
|
||||
|
||||
public ActionCommand(Action execute, Func<bool> canExecute = null)
|
||||
{
|
||||
_execute = execute;
|
||||
_canExecute = canExecute;
|
||||
}
|
||||
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
return _canExecute == null || _canExecute();
|
||||
}
|
||||
|
||||
public void Execute(object parameter)
|
||||
{
|
||||
_execute();
|
||||
}
|
||||
|
||||
public void RaiseCanExecuteChanged()
|
||||
{
|
||||
var handler = CanExecuteChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user