完成执行逻辑
This commit is contained in:
parent
b69a469c89
commit
691d894a12
22
BOB/Converters/InverseBooleanConverter.cs
Normal file
22
BOB/Converters/InverseBooleanConverter.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace BOB.Converters
|
||||||
|
{
|
||||||
|
public class InverseBooleanConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
// null 视为 false,再取反 → true
|
||||||
|
var b = value as bool?;
|
||||||
|
return !(b ?? false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
var b = value as bool?;
|
||||||
|
return !(b ?? false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,123 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Data;
|
|
||||||
|
|
||||||
namespace BOB.Converters
|
|
||||||
{
|
|
||||||
public class ParameterToGotoSettingStringConverter : IValueConverter
|
|
||||||
{
|
|
||||||
private GlobalVariables _globalVariables;
|
|
||||||
public ParameterToGotoSettingStringConverter(GlobalVariables globalVariables)
|
|
||||||
{
|
|
||||||
_globalVariables= globalVariables;
|
|
||||||
}
|
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
|
||||||
{
|
|
||||||
if (value is Guid stepID && stepID == _globalVariables.SelectedStep!.ID)
|
|
||||||
{
|
|
||||||
if (_globalVariables.SelectedStep == null)
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (_globalVariables.SelectedStep!.OKGotoStepID == null && _globalVariables.SelectedStep!.NGGotoStepID == null)
|
|
||||||
{
|
|
||||||
return "0/0";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string gotoString = "";
|
|
||||||
if (_globalVariables.SelectedStep!.OKGotoStepID != null)
|
|
||||||
{
|
|
||||||
var OKGotoStep = _globalVariables.Program.StepCollection.FirstOrDefault(x => x.ID == _globalVariables.SelectedStep!.OKGotoStepID);
|
|
||||||
if (OKGotoStep != null)
|
|
||||||
{
|
|
||||||
gotoString = OKGotoStep.Index.ToString() + "/";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gotoString = "0/";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gotoString = "0/";
|
|
||||||
}
|
|
||||||
if (_globalVariables.SelectedStep!.NGGotoStepID != null)
|
|
||||||
{
|
|
||||||
var NGGotoStep = _globalVariables.Program.StepCollection.FirstOrDefault(x => x.ID == _globalVariables.SelectedStep!.NGGotoStepID);
|
|
||||||
if (NGGotoStep != null)
|
|
||||||
{
|
|
||||||
gotoString += NGGotoStep.Index.ToString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gotoString += "0";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gotoString += "0";
|
|
||||||
}
|
|
||||||
return gotoString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
|
||||||
{
|
|
||||||
if (value is string gotoSettingstring)
|
|
||||||
{
|
|
||||||
gotoSettingstring = gotoSettingstring.Replace(" ", "").Replace("/n", "").Replace("/r", "");
|
|
||||||
if (gotoSettingstring == "0/0")
|
|
||||||
{
|
|
||||||
_globalVariables.SelectedStep!.OKGotoStepID = null;
|
|
||||||
_globalVariables.SelectedStep!.NGGotoStepID = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var list = gotoSettingstring.Split("/");
|
|
||||||
var okindex = System.Convert.ToInt32(list[0]);
|
|
||||||
var ngindex = System.Convert.ToInt32(list[1]);
|
|
||||||
if (okindex == 0)
|
|
||||||
{
|
|
||||||
_globalVariables.SelectedStep!.OKGotoStepID = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (okindex > _globalVariables.Program.StepCollection.Count)
|
|
||||||
{
|
|
||||||
throw new Exception("步骤序号超出最大值");
|
|
||||||
}
|
|
||||||
_globalVariables.SelectedStep!.OKGotoStepID = _globalVariables.Program.StepCollection.FirstOrDefault(x => x.Index == okindex)?.ID;
|
|
||||||
}
|
|
||||||
if (ngindex == 0)
|
|
||||||
{
|
|
||||||
_globalVariables.SelectedStep!.NGGotoStepID = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ngindex > _globalVariables.Program.StepCollection.Count)
|
|
||||||
{
|
|
||||||
throw new Exception("步骤序号超出最大值");
|
|
||||||
}
|
|
||||||
_globalVariables.SelectedStep!.NGGotoStepID = _globalVariables.Program.StepCollection.FirstOrDefault(x => x.Index == ngindex)?.ID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"跳转表达式错误:{ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _globalVariables.SelectedStep!.ID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using BOB.Models;
|
using BOB.Models;
|
||||||
|
using Common.PubEvent;
|
||||||
using Common.Tools;
|
using Common.Tools;
|
||||||
using Logger;
|
using Logger;
|
||||||
using MaterialDesignThemes.Wpf;
|
using MaterialDesignThemes.Wpf;
|
||||||
@ -18,6 +19,7 @@ namespace BOB
|
|||||||
public class StepRunning
|
public class StepRunning
|
||||||
{
|
{
|
||||||
private GlobalVariables _globalVariables;
|
private GlobalVariables _globalVariables;
|
||||||
|
private IEventAggregator _eventAggregator;
|
||||||
|
|
||||||
private readonly Dictionary<Guid, ParameterModel> tmpParameters = [];
|
private readonly Dictionary<Guid, ParameterModel> tmpParameters = [];
|
||||||
|
|
||||||
@ -31,9 +33,10 @@ namespace BOB
|
|||||||
private bool SubSingleStep = false;
|
private bool SubSingleStep = false;
|
||||||
|
|
||||||
private Guid TestRoundID;
|
private Guid TestRoundID;
|
||||||
public StepRunning(GlobalVariables globalVariables)
|
public StepRunning(GlobalVariables globalVariables,IEventAggregator eventAggregator)
|
||||||
{
|
{
|
||||||
_globalVariables = globalVariables;
|
_globalVariables = globalVariables;
|
||||||
|
_eventAggregator= eventAggregator;
|
||||||
}
|
}
|
||||||
public async Task<bool> ExecuteSteps(ProgramModel program, int depth = 0, CancellationToken cancellationToken = default)
|
public async Task<bool> ExecuteSteps(ProgramModel program, int depth = 0, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
@ -108,7 +111,7 @@ namespace BOB
|
|||||||
{
|
{
|
||||||
if (loopStack.Count == 0)
|
if (loopStack.Count == 0)
|
||||||
{
|
{
|
||||||
LoggerHelper.ErrorWithNotify("未匹配的循环结束指令", depth);
|
LoggerHelper.ErrorWithNotify("未匹配的循环结束指令", depth:depth);
|
||||||
step.Result = 2;
|
step.Result = 2;
|
||||||
index++;
|
index++;
|
||||||
continue;
|
continue;
|
||||||
@ -203,7 +206,8 @@ namespace BOB
|
|||||||
{
|
{
|
||||||
_globalVariables.IsStop = true;
|
_globalVariables.IsStop = true;
|
||||||
_globalVariables.RunState = "运行";
|
_globalVariables.RunState = "运行";
|
||||||
_globalVariables.RunIcon = PackIconKind.Play;
|
_globalVariables.SingleStep = false;
|
||||||
|
_eventAggregator.GetEvent<UpdateIconEvent>().Publish("Play");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,6 +219,7 @@ namespace BOB
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if(_globalVariables.Program.StepCollection.Count>1)
|
||||||
_globalVariables.SelectedStep = null;
|
_globalVariables.SelectedStep = null;
|
||||||
await Task.Delay(SystemConfig.Instance.PerformanceLevel);
|
await Task.Delay(SystemConfig.Instance.PerformanceLevel);
|
||||||
|
|
||||||
@ -227,7 +232,7 @@ namespace BOB
|
|||||||
}
|
}
|
||||||
if (targetType == null)
|
if (targetType == null)
|
||||||
{
|
{
|
||||||
LoggerHelper.ErrorWithNotify($"指令 [ {step.Index} ] 执行错误:未找到类型 {step.Method!.FullName}", depth);
|
LoggerHelper.ErrorWithNotify($"指令 [ {step.Index} ] 执行错误:未找到类型 {step.Method!.FullName}", depth: depth);
|
||||||
step.Result = 2;
|
step.Result = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +323,7 @@ namespace BOB
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LoggerHelper.WarnWithNotify($"指令 [ {step.Index} ] 执行错误:参数 {param.Name} 类型转换失败: {ex.Message}", depth);
|
LoggerHelper.WarnWithNotify($"指令 [ {step.Index} ] 执行错误:参数 {param.Name} 类型转换失败: {ex.Message}", depth: depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,7 +347,7 @@ namespace BOB
|
|||||||
|
|
||||||
if (method == null)
|
if (method == null)
|
||||||
{
|
{
|
||||||
LoggerHelper.ErrorWithNotify($"指令 [ {step.Index} ] 执行错误:未找到方法{step.Method.Name}", depth);
|
LoggerHelper.ErrorWithNotify($"指令 [ {step.Index} ] 执行错误:未找到方法{step.Method.Name}", depth: depth);
|
||||||
step.Result = 2;
|
step.Result = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +355,7 @@ namespace BOB
|
|||||||
bool isStaticMethod = method!.IsStatic;
|
bool isStaticMethod = method!.IsStatic;
|
||||||
|
|
||||||
// 如果是实例方法,需要创建实例
|
// 如果是实例方法,需要创建实例
|
||||||
if (!isMethod)
|
if (!isStaticMethod)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -358,7 +363,7 @@ namespace BOB
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LoggerHelper.ErrorWithNotify($"指令 [ {step.Index} ] 执行错误:创建实例失败 - {ex.Message}", depth);
|
LoggerHelper.ErrorWithNotify($"指令 [ {step.Index} ] 执行错误:创建实例失败 - {ex.Message}", depth: depth);
|
||||||
step.Result = 2;
|
step.Result = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,7 +401,7 @@ namespace BOB
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LoggerHelper.ErrorWithNotify($"指令 [ {step.Index} ] 执行错误: {ex.InnerException?.Message ?? ex.Message}", depth);
|
LoggerHelper.ErrorWithNotify($"指令 [ {step.Index} ] 执行错误: {ex.InnerException?.Message ?? ex.Message}", depth: depth);
|
||||||
step.Result = 2;
|
step.Result = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -448,7 +453,7 @@ namespace BOB
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LoggerHelper.ErrorWithNotify($"指令 [ {step.Index} ] 执行错误: {ex.InnerException?.Message ?? ex.Message}", depth);
|
LoggerHelper.ErrorWithNotify($"指令 [ {step.Index} ] 执行错误: {ex.InnerException?.Message ?? ex.Message}", depth: depth);
|
||||||
step.Result = 2;
|
step.Result = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -496,7 +501,7 @@ namespace BOB
|
|||||||
step.Result = re ? 1 : 2;
|
step.Result = re ? 1 : 2;
|
||||||
if (step.Result == 2)
|
if (step.Result == 2)
|
||||||
{
|
{
|
||||||
LoggerHelper.WarnWithNotify($"指令 [ {step.Index} ] NG:条件表达式验证失败", depth);
|
LoggerHelper.WarnWithNotify($"指令 [ {step.Index} ] NG:条件表达式验证失败", depth: depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,7 +509,7 @@ namespace BOB
|
|||||||
{
|
{
|
||||||
if (!paraResult)
|
if (!paraResult)
|
||||||
{
|
{
|
||||||
LoggerHelper.WarnWithNotify("参数限值校验失败", depth);
|
LoggerHelper.WarnWithNotify("参数限值校验失败", depth: depth);
|
||||||
}
|
}
|
||||||
step.Result = 2;
|
step.Result = 2;
|
||||||
}
|
}
|
||||||
@ -129,6 +129,10 @@ namespace BOB.ViewModels
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(Node.Tag is SubProgramItem subProgram)
|
||||||
|
{
|
||||||
|
AddSubProgramToProgram(subProgram, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,7 +199,7 @@ namespace BOB.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var filePath in Directory.GetFiles(SystemConfig.Instance.SubProgramFilePath, "*.ats"))
|
foreach (var filePath in Directory.GetFiles(SystemConfig.Instance.SubProgramFilePath, "*.bob"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -470,45 +474,42 @@ namespace BOB.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//private void AddSubProgramToProgram(SubProgramItem subProgram, int insertIndex = -1)
|
private void AddSubProgramToProgram(SubProgramItem subProgram, int insertIndex = -1)
|
||||||
//{
|
{
|
||||||
// try
|
try
|
||||||
// {
|
{
|
||||||
// var newStep = new StepModel
|
var newStep = new StepModel
|
||||||
// {
|
{
|
||||||
// Name = subProgram.Name,
|
Name = subProgram.Name,
|
||||||
// StepType = "子程序"
|
StepType = "子程序"
|
||||||
// };
|
};
|
||||||
// var jsonstr = File.ReadAllText($"{subProgram.FilePath}");
|
var jsonstr = File.ReadAllText($"{subProgram.FilePath}");
|
||||||
// var tmp = JsonConvert.DeserializeObject<ProgramModel>(jsonstr);
|
var tmp = JsonConvert.DeserializeObject<ProgramModel>(jsonstr);
|
||||||
// if (tmp != null)
|
if (tmp != null)
|
||||||
// {
|
{
|
||||||
// if (tmp.Devices != null && tmp.Devices.Count > 0)
|
if (tmp.Devices != null && tmp.Devices.Count > 0)
|
||||||
// {
|
{
|
||||||
// foreach (var device in tmp.Devices)
|
foreach (var device in tmp.Devices)
|
||||||
// {
|
{
|
||||||
// _ = DeviceConnect.InitAndConnectDevice(tmp, device);
|
// _ = DeviceConnect.InitAndConnectDevice(tmp, device);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// newStep.SubProgram = tmp;
|
newStep.SubProgram = tmp;
|
||||||
// }
|
}
|
||||||
// 添加到程序
|
if (insertIndex >= 0 && insertIndex <= Program.StepCollection.Count)
|
||||||
// if (insertIndex >= 0 && insertIndex <= Program.StepCollection.Count)
|
{
|
||||||
// {
|
Program.StepCollection.Insert(insertIndex, newStep);
|
||||||
// Program.StepCollection.Insert(insertIndex, newStep);
|
}
|
||||||
// }
|
else
|
||||||
// else
|
{
|
||||||
// {
|
Program.StepCollection.Add(newStep);
|
||||||
// Program.StepCollection.Add(newStep);
|
}
|
||||||
// }
|
}
|
||||||
|
catch (Exception ex)
|
||||||
// ReOrderProgramList();
|
{
|
||||||
// }
|
LoggerHelper.ErrorWithNotify($"添加子程序失败: {subProgram.Name} - {ex.Message}");
|
||||||
// catch (Exception ex)
|
}
|
||||||
// {
|
}
|
||||||
// Log.Error($"添加子程序失败: {subProgram.Name} - {ex.Message}");
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
private void AddLoopStartStep(int insertIndex = -1)
|
private void AddLoopStartStep(int insertIndex = -1)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using BOB.Models;
|
using BOB.Models;
|
||||||
|
using Common.PubEvent;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -62,11 +63,13 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
#endregion
|
#endregion
|
||||||
public DialogCloseListener RequestClose { get; set; }
|
public DialogCloseListener RequestClose { get; set; }
|
||||||
private GlobalVariables _globalVariables;
|
private GlobalVariables _globalVariables;
|
||||||
|
private IEventAggregator _eventAggregator;
|
||||||
public ICommand CancelCommand { get; set; }
|
public ICommand CancelCommand { get; set; }
|
||||||
public ICommand SaveCommand { get; set; }
|
public ICommand SaveCommand { get; set; }
|
||||||
public ICommand SelectionChangedCommand { get; set; }
|
public ICommand SelectionChangedCommand { get; set; }
|
||||||
public DeviceSettingViewModel(GlobalVariables globalVariables)
|
public DeviceSettingViewModel(GlobalVariables globalVariables, IEventAggregator eventAggregator)
|
||||||
{
|
{
|
||||||
|
_eventAggregator = eventAggregator;
|
||||||
_globalVariables = globalVariables;
|
_globalVariables = globalVariables;
|
||||||
CancelCommand = new DelegateCommand(Cancel);
|
CancelCommand = new DelegateCommand(Cancel);
|
||||||
SaveCommand = new DelegateCommand(Save);
|
SaveCommand = new DelegateCommand(Save);
|
||||||
@ -183,11 +186,12 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
|
|
||||||
public void OnDialogClosed()
|
public void OnDialogClosed()
|
||||||
{
|
{
|
||||||
|
_eventAggregator.GetEvent<OverlayEvent>().Publish(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnDialogOpened(IDialogParameters parameters)
|
public void OnDialogOpened(IDialogParameters parameters)
|
||||||
{
|
{
|
||||||
|
_eventAggregator.GetEvent<OverlayEvent>().Publish(true);
|
||||||
Program = _globalVariables.Program;
|
Program = _globalVariables.Program;
|
||||||
Mode = parameters.GetValue<string>("Mode");
|
Mode = parameters.GetValue<string>("Mode");
|
||||||
if(Mode == "ADD")
|
if(Mode == "ADD")
|
||||||
|
|||||||
@ -100,6 +100,7 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
|
|
||||||
public void OnDialogOpened(IDialogParameters parameters)
|
public void OnDialogOpened(IDialogParameters parameters)
|
||||||
{
|
{
|
||||||
|
_eventAggregator.GetEvent<OverlayEvent>().Publish(true);
|
||||||
Title = parameters.GetValue<string>("Title");
|
Title = parameters.GetValue<string>("Title");
|
||||||
Message = parameters.GetValue<string>("Message");
|
Message = parameters.GetValue<string>("Message");
|
||||||
var iconKey = parameters.GetValue<string>("Icon"); // info / error / warn
|
var iconKey = parameters.GetValue<string>("Icon"); // info / error / warn
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using BOB.Models;
|
using BOB.Models;
|
||||||
|
using Common.PubEvent;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -69,10 +70,12 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
#endregion
|
#endregion
|
||||||
public DialogCloseListener RequestClose{get;set;}
|
public DialogCloseListener RequestClose{get;set;}
|
||||||
private GlobalVariables _globalVariables;
|
private GlobalVariables _globalVariables;
|
||||||
|
private IEventAggregator _eventAggregator;
|
||||||
public ICommand CancelCommand { get; set; }
|
public ICommand CancelCommand { get; set; }
|
||||||
public ICommand SaveCommand { get; set; }
|
public ICommand SaveCommand { get; set; }
|
||||||
public ParameterSettingViewModel(GlobalVariables globalVariables)
|
public ParameterSettingViewModel(GlobalVariables globalVariables, IEventAggregator eventAggregator)
|
||||||
{
|
{
|
||||||
|
_eventAggregator = eventAggregator;
|
||||||
_globalVariables = globalVariables;
|
_globalVariables = globalVariables;
|
||||||
CancelCommand = new DelegateCommand(Cancel);
|
CancelCommand = new DelegateCommand(Cancel);
|
||||||
SaveCommand = new DelegateCommand(Save);
|
SaveCommand = new DelegateCommand(Save);
|
||||||
@ -112,12 +115,13 @@ namespace BOB.ViewModels.Dialogs
|
|||||||
|
|
||||||
public void OnDialogClosed()
|
public void OnDialogClosed()
|
||||||
{
|
{
|
||||||
|
_eventAggregator.GetEvent<OverlayEvent>().Publish(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnDialogOpened(IDialogParameters parameters)
|
public void OnDialogOpened(IDialogParameters parameters)
|
||||||
{
|
{
|
||||||
Program=_globalVariables.Program;
|
_eventAggregator.GetEvent<OverlayEvent>().Publish(true);
|
||||||
|
Program =_globalVariables.Program;
|
||||||
Mode = parameters.GetValue<string>("Mode");
|
Mode = parameters.GetValue<string>("Mode");
|
||||||
if (Mode == "ADD")
|
if (Mode == "ADD")
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using Prism.Mvvm;
|
using Prism.Mvvm;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
||||||
@ -16,18 +17,21 @@ namespace BOB.ViewModels
|
|||||||
get => _logs;
|
get => _logs;
|
||||||
set => SetProperty(ref _logs, value);
|
set => SetProperty(ref _logs, value);
|
||||||
}
|
}
|
||||||
|
public ICommand ClearLogCommand { get; set; }
|
||||||
public LogAreaViewModel()
|
public LogAreaViewModel()
|
||||||
{
|
{
|
||||||
LoggerHelper.LogAdded += OnLogAdded;
|
ClearLogCommand = new DelegateCommand(ClearLog);
|
||||||
|
LoggerHelper.Progress = new System.Progress<(string message, string color,int depth)>(
|
||||||
|
log =>
|
||||||
|
{
|
||||||
|
var brush = (Brush)new BrushConverter().ConvertFromString(log.color);
|
||||||
|
Logs.Add(new LogItem(log.message, brush, log.depth));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 方便外部添加日志
|
private void ClearLog()
|
||||||
public void OnLogAdded(string message, string color)
|
|
||||||
{
|
{
|
||||||
var brush = (Brush)new BrushConverter().ConvertFromString(color);
|
Logs.Clear();
|
||||||
Application.Current.Dispatcher.Invoke(() => Logs.Add(new LogItem { Message = message, Color = brush }));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,5 +40,12 @@ namespace BOB.ViewModels
|
|||||||
{
|
{
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public Brush Color { get; set; } = Brushes.Black;
|
public Brush Color { get; set; } = Brushes.Black;
|
||||||
|
public int Depth { get; set; }
|
||||||
|
public LogItem(string message, Brush color, int depth = 0)
|
||||||
|
{
|
||||||
|
Message = new string(' ', depth * 20) + message;
|
||||||
|
Color = color;
|
||||||
|
Depth = depth;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,13 +97,12 @@ namespace BOB.ViewModels
|
|||||||
{
|
{
|
||||||
if (r.Result == ButtonResult.OK)
|
if (r.Result == ButtonResult.OK)
|
||||||
{
|
{
|
||||||
|
_eventAggregator.GetEvent<ParamsChangedEvent>().Publish();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
_eventAggregator.GetEvent<OverlayEvent>().Publish(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -114,18 +113,16 @@ namespace BOB.ViewModels
|
|||||||
{
|
{
|
||||||
{ "Mode", "ADD" }
|
{ "Mode", "ADD" }
|
||||||
};
|
};
|
||||||
_eventAggregator.GetEvent<OverlayEvent>().Publish(true);
|
|
||||||
_dialogService.ShowDialog("DeviceSetting", param, (r) =>
|
_dialogService.ShowDialog("DeviceSetting", param, (r) =>
|
||||||
{
|
{
|
||||||
if (r.Result == ButtonResult.OK)
|
if (r.Result == ButtonResult.OK)
|
||||||
{
|
{
|
||||||
|
_eventAggregator.GetEvent<ParamsChangedEvent>().Publish();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
_eventAggregator.GetEvent<OverlayEvent>().Publish(false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,13 +141,13 @@ namespace BOB.ViewModels
|
|||||||
{
|
{
|
||||||
if (r.Result == ButtonResult.OK)
|
if (r.Result == ButtonResult.OK)
|
||||||
{
|
{
|
||||||
|
_eventAggregator.GetEvent<ParamsChangedEvent>().Publish();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
_eventAggregator.GetEvent<OverlayEvent>().Publish(false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,13 +161,13 @@ namespace BOB.ViewModels
|
|||||||
{
|
{
|
||||||
if (r.Result == ButtonResult.OK)
|
if (r.Result == ButtonResult.OK)
|
||||||
{
|
{
|
||||||
|
_eventAggregator.GetEvent<ParamsChangedEvent>().Publish();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
_eventAggregator.GetEvent<OverlayEvent>().Publish(false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using BOB.Models;
|
using BOB.Models;
|
||||||
using BOB.Views;
|
using BOB.Views;
|
||||||
|
using Common.PubEvent;
|
||||||
using Common.PubEvents;
|
using Common.PubEvents;
|
||||||
using Logger;
|
using Logger;
|
||||||
using MaterialDesignThemes.Wpf;
|
using MaterialDesignThemes.Wpf;
|
||||||
@ -28,6 +29,13 @@ namespace BOB.ViewModels
|
|||||||
get => _IsLeftDrawerOpen;
|
get => _IsLeftDrawerOpen;
|
||||||
set => SetProperty(ref _IsLeftDrawerOpen, value);
|
set => SetProperty(ref _IsLeftDrawerOpen, value);
|
||||||
}
|
}
|
||||||
|
private bool _IsTerminate=false;
|
||||||
|
|
||||||
|
public bool IsTerminate
|
||||||
|
{
|
||||||
|
get => _IsTerminate;
|
||||||
|
set => SetProperty(ref _IsTerminate, value);
|
||||||
|
}
|
||||||
|
|
||||||
public String RunState
|
public String RunState
|
||||||
{
|
{
|
||||||
@ -109,6 +117,17 @@ namespace BOB.ViewModels
|
|||||||
SaveCommand = new DelegateCommand(Save);
|
SaveCommand = new DelegateCommand(Save);
|
||||||
SetDefaultCommand = new DelegateCommand(SetDefault);
|
SetDefaultCommand = new DelegateCommand(SetDefault);
|
||||||
LoadCommand = new DelegateCommand(Load);
|
LoadCommand = new DelegateCommand(Load);
|
||||||
|
_eventAggregator.GetEvent<UpdateIconEvent>().Subscribe(UpdateRunIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRunIcon(string obj)
|
||||||
|
{
|
||||||
|
RunIcon= obj switch
|
||||||
|
{
|
||||||
|
"Play" => PackIconKind.Play,
|
||||||
|
"Pause" => PackIconKind.Pause,
|
||||||
|
_ => RunIcon
|
||||||
|
};
|
||||||
}
|
}
|
||||||
#region ToolBar命令
|
#region ToolBar命令
|
||||||
private void Load()
|
private void Load()
|
||||||
@ -206,11 +225,10 @@ namespace BOB.ViewModels
|
|||||||
{
|
{
|
||||||
_globalVariables.CurrentFilePath = saveFileDialog.FileName;
|
_globalVariables.CurrentFilePath = saveFileDialog.FileName;
|
||||||
SaveProgramToFile(_globalVariables.CurrentFilePath);
|
SaveProgramToFile(_globalVariables.CurrentFilePath);
|
||||||
|
// 记录日志
|
||||||
|
LoggerHelper.InfoWithNotify($"{_globalVariables.UserName} 另存为文件成功: {saveFileDialog.FileName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录日志
|
|
||||||
LoggerHelper.InfoWithNotify($"{_globalVariables.UserName} 另存为文件成功: {saveFileDialog.FileName}");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
private void SaveProgramToFile(string filePath)
|
private void SaveProgramToFile(string filePath)
|
||||||
{
|
{
|
||||||
@ -251,16 +269,29 @@ namespace BOB.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SaveProgramToFile(_globalVariables.CurrentFilePath);
|
SaveProgramToFile(_globalVariables.CurrentFilePath);
|
||||||
LoggerHelper.InfoWithNotify(_globalVariables.UserName + "保存文件成功");
|
|
||||||
}
|
}
|
||||||
private void Stop()
|
private void Stop()
|
||||||
{
|
{
|
||||||
LoggerHelper.InfoWithNotify(_globalVariables.UserName+"执行停止命令");
|
if (_globalVariables.IsStop == false)
|
||||||
|
{
|
||||||
|
LoggerHelper.InfoWithNotify(_globalVariables.UserName + "执行停止命令");
|
||||||
|
IsTerminate = true;
|
||||||
|
_globalVariables.IsStop = null;
|
||||||
|
RunState = "运行";
|
||||||
|
RunIcon = PackIconKind.Play;
|
||||||
|
_stepRunning.stepCTS.Cancel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Resotration()
|
private void Resotration()
|
||||||
{
|
{
|
||||||
LoggerHelper.InfoWithNotify(_globalVariables.UserName + "执行复位命令");
|
LoggerHelper.InfoWithNotify(_globalVariables.UserName + "执行复位命令");
|
||||||
|
IsTerminate = false;
|
||||||
|
currentExecutionTask = null;
|
||||||
|
_stepRunning.stepCTS = new();
|
||||||
|
_globalVariables.IsStop = null;
|
||||||
|
_stepRunning.ResetAllStepStatus(_globalVariables.Program);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void RunSingle()
|
private async void RunSingle()
|
||||||
@ -274,11 +305,12 @@ namespace BOB.ViewModels
|
|||||||
if (_globalVariables.IsStop == null)
|
if (_globalVariables.IsStop == null)
|
||||||
{
|
{
|
||||||
_globalVariables.IsStop = false;
|
_globalVariables.IsStop = false;
|
||||||
currentExecutionTask = _stepRunning.ExecuteSteps(_globalVariables.Program, cancellationToken: _stepRunning.stepCTS.Token);
|
if(currentExecutionTask==null)currentExecutionTask = _stepRunning.ExecuteSteps(_globalVariables.Program, cancellationToken: _stepRunning.stepCTS.Token);
|
||||||
await currentExecutionTask;
|
await currentExecutionTask;
|
||||||
RunState = "运行";
|
RunState = "运行";
|
||||||
RunIcon = PackIconKind.Play;
|
RunIcon = PackIconKind.Play;
|
||||||
_globalVariables.IsStop = null;
|
_globalVariables.IsStop = null;
|
||||||
|
IsTerminate = true;
|
||||||
}
|
}
|
||||||
else if (_globalVariables.IsStop == true)
|
else if (_globalVariables.IsStop == true)
|
||||||
{
|
{
|
||||||
@ -299,11 +331,12 @@ namespace BOB.ViewModels
|
|||||||
if (_globalVariables.IsStop == null)
|
if (_globalVariables.IsStop == null)
|
||||||
{
|
{
|
||||||
_globalVariables.IsStop = false;
|
_globalVariables.IsStop = false;
|
||||||
currentExecutionTask = _stepRunning.ExecuteSteps(_globalVariables.Program, cancellationToken: _stepRunning.stepCTS.Token);
|
if (currentExecutionTask == null) currentExecutionTask = _stepRunning.ExecuteSteps(_globalVariables.Program, cancellationToken: _stepRunning.stepCTS.Token);
|
||||||
await currentExecutionTask;
|
await currentExecutionTask;
|
||||||
RunState = "运行";
|
RunState = "运行";
|
||||||
RunIcon = PackIconKind.Play;
|
RunIcon = PackIconKind.Play;
|
||||||
_globalVariables.IsStop = null;
|
_globalVariables.IsStop = null;
|
||||||
|
IsTerminate = true;
|
||||||
}
|
}
|
||||||
else if (_globalVariables.IsStop == true)
|
else if (_globalVariables.IsStop == true)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
using BOB.Models;
|
using BOB.Models;
|
||||||
using Common.PubEvent;
|
using Common.PubEvent;
|
||||||
|
using Logger;
|
||||||
|
using Microsoft.IdentityModel.Logging;
|
||||||
|
using SqlSugar.Extensions;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace BOB.ViewModels
|
namespace BOB.ViewModels
|
||||||
@ -39,16 +44,24 @@ namespace BOB.ViewModels
|
|||||||
#endregion
|
#endregion
|
||||||
private GlobalVariables _globalVariables;
|
private GlobalVariables _globalVariables;
|
||||||
private IEventAggregator _eventAggregator;
|
private IEventAggregator _eventAggregator;
|
||||||
|
private IDialogService _dialogService;
|
||||||
public ICommand CancelEditCommand { get; set; }
|
public ICommand CancelEditCommand { get; set; }
|
||||||
public ICommand SaveStepCommand { get; set; }
|
public ICommand SaveStepCommand { get; set; }
|
||||||
public SingleStepEditViewModel(GlobalVariables globalVariables,IEventAggregator eventAggregator)
|
public SingleStepEditViewModel(GlobalVariables globalVariables,IEventAggregator eventAggregator,IDialogService dialogService)
|
||||||
{
|
{
|
||||||
_globalVariables= globalVariables;
|
_globalVariables= globalVariables;
|
||||||
_eventAggregator= eventAggregator;
|
_eventAggregator= eventAggregator;
|
||||||
|
_dialogService = dialogService;
|
||||||
_eventAggregator.GetEvent<EditSetpEvent>().Subscribe(EditSingleSetp);
|
_eventAggregator.GetEvent<EditSetpEvent>().Subscribe(EditSingleSetp);
|
||||||
CancelEditCommand = new DelegateCommand(CancelEdit);
|
CancelEditCommand = new DelegateCommand(CancelEdit);
|
||||||
SaveStepCommand = new DelegateCommand(SaveStep);
|
SaveStepCommand = new DelegateCommand(SaveStep);
|
||||||
_eventAggregator.GetEvent<DeletedStepEvent>().Subscribe(DisposeSelectedStep);
|
_eventAggregator.GetEvent<DeletedStepEvent>().Subscribe(DisposeSelectedStep);
|
||||||
|
_eventAggregator.GetEvent<ParamsChangedEvent>().Subscribe(ParamsChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParamsChanged()
|
||||||
|
{
|
||||||
|
CancelEdit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisposeSelectedStep(Guid id)
|
private void DisposeSelectedStep(Guid id)
|
||||||
@ -74,10 +87,105 @@ namespace BOB.ViewModels
|
|||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
steps[index] = SelectedStep;
|
steps[index] = SelectedStep;
|
||||||
|
if (steps[index].Method != null)
|
||||||
|
{
|
||||||
|
if (steps[index].StepType == "循环开始")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
steps[index].LoopCount = Convert.ToInt32(SelectedStep.Method!.Parameters[0].Value);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
LoggerHelper.ErrorWithNotify("循环指令参数设置错误:类型转换失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(steps[index].OKGotoStepID, steps[index].NGGotoStepID) = GetOKNGGotoStepID(SelectedStep.GotoSettingString);
|
||||||
|
for (int i = 0; i < steps[index].Method.Parameters.Count; i++)
|
||||||
|
{
|
||||||
|
var editedParam = SelectedStep.Method!.Parameters[i];
|
||||||
|
var originalParam = steps[index].Method.Parameters[i];
|
||||||
|
if (editedParam.IsUseVar)
|
||||||
|
{
|
||||||
|
originalParam.VariableName = editedParam.VariableName;
|
||||||
|
originalParam.VariableID = _globalVariables.Program.Parameters.FirstOrDefault(x => x.Name == editedParam.VariableName)!.ID;
|
||||||
|
}
|
||||||
|
originalParam.Value = editedParam.Value;
|
||||||
|
originalParam.IsUseVar = editedParam.IsUseVar;
|
||||||
|
originalParam.LowerLimit = editedParam.LowerLimit;
|
||||||
|
originalParam.UpperLimit = editedParam.UpperLimit;
|
||||||
|
}
|
||||||
|
var parameters = new DialogParameters
|
||||||
|
{
|
||||||
|
{ "Title", "提示" },
|
||||||
|
{ "Message", "保存成功!" },
|
||||||
|
{ "Icon", "info" },
|
||||||
|
{ "ShowOk", true }
|
||||||
|
};
|
||||||
|
_dialogService.ShowDialog("MessageBox", parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (steps[index].SubProgram != null)
|
||||||
|
{
|
||||||
|
if (SelectedStep.SubProgram.Parameters.Where(x => x.VariableName == null && x.IsUseVar == true).FirstOrDefault() != null)
|
||||||
|
{
|
||||||
|
var parameters1 = new DialogParameters
|
||||||
|
{
|
||||||
|
{ "Title", "警告" },
|
||||||
|
{ "Message", "选中变量不得为空!" },
|
||||||
|
{ "Icon", "warn" },
|
||||||
|
{ "ShowOk", true },
|
||||||
|
};
|
||||||
|
_dialogService.ShowDialog("MessageBox",parameters1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(steps[index].OKGotoStepID, steps[index].NGGotoStepID) = GetOKNGGotoStepID(SelectedStep.GotoSettingString);
|
||||||
|
for (int i = 0; i < steps[index].SubProgram.Parameters.Count; i++)
|
||||||
|
{
|
||||||
|
var editedParam = SelectedStep.SubProgram!.Parameters[i];
|
||||||
|
var originalParam = steps[index].SubProgram.Parameters[i];
|
||||||
|
if (editedParam.IsUseVar)
|
||||||
|
{
|
||||||
|
originalParam.VariableName = editedParam.VariableName;
|
||||||
|
originalParam.VariableID = _globalVariables.Program.Parameters.FirstOrDefault(x => x.Name == editedParam.VariableName)!.ID;
|
||||||
|
}
|
||||||
|
originalParam.Value = editedParam.Value;
|
||||||
|
originalParam.IsUseVar = editedParam.IsUseVar;
|
||||||
|
originalParam.LowerLimit = editedParam.LowerLimit;
|
||||||
|
originalParam.UpperLimit = editedParam.UpperLimit;
|
||||||
|
}
|
||||||
|
var parameters = new DialogParameters
|
||||||
|
{
|
||||||
|
{ "Title", "提示" },
|
||||||
|
{ "Message", "保存成功!" },
|
||||||
|
{ "Icon", "info" },
|
||||||
|
{ "ShowOk", true }
|
||||||
|
};
|
||||||
|
_dialogService.ShowDialog("MessageBox", parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private (Guid,Guid) GetOKNGGotoStepID(string GotoSettingString)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(GotoSettingString))
|
||||||
|
return (Guid.Empty, Guid.Empty);
|
||||||
|
|
||||||
|
var match = Regex.Match(GotoSettingString, @"^(\d+)\s*/\s*(\d+)$");
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
int ok = int.Parse(match.Groups[1].Value);
|
||||||
|
int ng = int.Parse(match.Groups[2].Value);
|
||||||
|
|
||||||
|
Guid okGuid = _globalVariables.Program.StepCollection.ElementAtOrDefault(ok-1)?.ID ?? Guid.Empty;
|
||||||
|
Guid ngGuid = _globalVariables.Program.StepCollection.ElementAtOrDefault(ng-1)?.ID ?? Guid.Empty;
|
||||||
|
|
||||||
|
return (okGuid, ngGuid);
|
||||||
|
}
|
||||||
|
return (Guid.Empty, Guid.Empty);
|
||||||
|
}
|
||||||
private void EditSingleSetp()
|
private void EditSingleSetp()
|
||||||
{
|
{
|
||||||
ID = _globalVariables.SelectedStep.ID;
|
ID = _globalVariables.SelectedStep.ID;
|
||||||
|
|||||||
@ -11,10 +11,16 @@
|
|||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<GroupBox Header="系统运行日志">
|
<GroupBox Header="系统运行日志">
|
||||||
<ListView FontWeight="DemiBold"
|
<ListView x:Name="LogListView"
|
||||||
|
FontWeight="DemiBold"
|
||||||
ItemsSource="{Binding Logs}"
|
ItemsSource="{Binding Logs}"
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||||
|
<ListView.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Header="清空日志"
|
||||||
|
Command="{Binding ClearLogCommand}" />
|
||||||
|
</ContextMenu>
|
||||||
|
</ListView.ContextMenu>
|
||||||
<ListView.ItemTemplate>
|
<ListView.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<TextBlock Foreground="{Binding Color}"
|
<TextBlock Foreground="{Binding Color}"
|
||||||
|
|||||||
@ -1,28 +1,34 @@
|
|||||||
using System;
|
using BOB.ViewModels;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
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 BOB.Views
|
namespace BOB.Views
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// LogArea.xaml 的交互逻辑
|
|
||||||
/// </summary>
|
|
||||||
public partial class LogArea : UserControl
|
public partial class LogArea : UserControl
|
||||||
{
|
{
|
||||||
public LogArea()
|
public LogArea()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
// 绑定 DataContext 后,订阅日志集合变化
|
||||||
|
this.Loaded += (s, e) =>
|
||||||
|
{
|
||||||
|
if (DataContext is LogAreaViewModel vm)
|
||||||
|
{
|
||||||
|
vm.Logs.CollectionChanged += Logs_CollectionChanged;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Logs_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
// 每次新增日志,滚动到最后一条
|
||||||
|
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
|
||||||
|
{
|
||||||
|
if (this.LogListView.Items.Count > 0)
|
||||||
|
{
|
||||||
|
this.LogListView.ScrollIntoView(this.LogListView.Items[^1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
WindowStartupLocation="CenterScreen"
|
WindowStartupLocation="CenterScreen"
|
||||||
Topmost="false"
|
xmlns:converter="clr-namespace:BOB.Converters"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
WindowStyle="None"
|
WindowStyle="None"
|
||||||
@ -23,7 +23,9 @@
|
|||||||
<i:InvokeCommandAction Command="{Binding LoadCommand}" />
|
<i:InvokeCommandAction Command="{Binding LoadCommand}" />
|
||||||
</i:EventTrigger>
|
</i:EventTrigger>
|
||||||
</i:Interaction.Triggers>
|
</i:Interaction.Triggers>
|
||||||
|
<Window.Resources>
|
||||||
|
<converter:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||||
|
</Window.Resources>
|
||||||
<materialDesign:DrawerHost x:Name="MainDrawerHost"
|
<materialDesign:DrawerHost x:Name="MainDrawerHost"
|
||||||
IsLeftDrawerOpen="{Binding IsLeftDrawerOpen, Mode=TwoWay}">
|
IsLeftDrawerOpen="{Binding IsLeftDrawerOpen, Mode=TwoWay}">
|
||||||
|
|
||||||
@ -146,6 +148,7 @@
|
|||||||
<MenuItem FontSize="14"
|
<MenuItem FontSize="14"
|
||||||
Height="50"
|
Height="50"
|
||||||
Header="运行"
|
Header="运行"
|
||||||
|
IsEnabled="{Binding IsTerminate, Converter={StaticResource InverseBooleanConverter}}"
|
||||||
Command="{Binding RunningCommand}"
|
Command="{Binding RunningCommand}"
|
||||||
Foreground="White">
|
Foreground="White">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@ -156,6 +159,7 @@
|
|||||||
<MenuItem FontSize="14"
|
<MenuItem FontSize="14"
|
||||||
Height="50"
|
Height="50"
|
||||||
Header="单步执行"
|
Header="单步执行"
|
||||||
|
IsEnabled="{Binding IsTerminate, Converter={StaticResource InverseBooleanConverter}}"
|
||||||
Command="{Binding RunSingleCommand}"
|
Command="{Binding RunSingleCommand}"
|
||||||
Foreground="White">
|
Foreground="White">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@ -176,6 +180,7 @@
|
|||||||
<MenuItem FontSize="14"
|
<MenuItem FontSize="14"
|
||||||
Height="50"
|
Height="50"
|
||||||
Header="复位"
|
Header="复位"
|
||||||
|
IsEnabled="{Binding IsTerminate}"
|
||||||
Command="{Binding ResotrationCommand}"
|
Command="{Binding ResotrationCommand}"
|
||||||
Foreground="White">
|
Foreground="White">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
@ -241,15 +246,15 @@
|
|||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="454*" />
|
<ColumnDefinition Width="454*" />
|
||||||
<ColumnDefinition Width="91*" />
|
<ColumnDefinition Width="91*" />
|
||||||
<ColumnDefinition Width="1375*" />
|
<ColumnDefinition Width="57*" />
|
||||||
|
<ColumnDefinition Width="1319*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<ContentControl prism:RegionManager.RegionName="ShellViewManager"
|
<ContentControl prism:RegionManager.RegionName="ShellViewManager"
|
||||||
Grid.ColumnSpan="3" />
|
Grid.ColumnSpan="4" />
|
||||||
<Border x:Name="Overlay"
|
<Border x:Name="Overlay"
|
||||||
Background="#40000000"
|
Background="#40000000"
|
||||||
Visibility="Collapsed"
|
Visibility="Collapsed"
|
||||||
Panel.ZIndex="10"
|
Panel.ZIndex="10"
|
||||||
Grid.RowSpan="2"
|
|
||||||
Grid.ColumnSpan="4" />
|
Grid.ColumnSpan="4" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</materialDesign:DialogHost>
|
</materialDesign:DialogHost>
|
||||||
|
|||||||
@ -325,7 +325,7 @@
|
|||||||
Margin="0,0,0,0"
|
Margin="0,0,0,0"
|
||||||
materialDesign:HintAssist.Hint=""
|
materialDesign:HintAssist.Hint=""
|
||||||
VerticalAlignment="Bottom"
|
VerticalAlignment="Bottom"
|
||||||
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.Program.Parameters}"
|
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.Program.Parameters}"
|
||||||
SelectedValue="{Binding VariableName}"
|
SelectedValue="{Binding VariableName}"
|
||||||
SelectedValuePath="Name"
|
SelectedValuePath="Name"
|
||||||
Visibility="{Binding Category, Converter={StaticResource ParameterCategoryToVisibilityConverter}, ConverterParameter=Inverse}">
|
Visibility="{Binding Category, Converter={StaticResource ParameterCategoryToVisibilityConverter}, ConverterParameter=Inverse}">
|
||||||
|
|||||||
12
Common/PubEvent/ParamsChangedEvent.cs
Normal file
12
Common/PubEvent/ParamsChangedEvent.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Common.PubEvent
|
||||||
|
{
|
||||||
|
public class ParamsChangedEvent:PubSubEvent
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Common/PubEvent/UpdateIconEvent.cs
Normal file
12
Common/PubEvent/UpdateIconEvent.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Common.PubEvent
|
||||||
|
{
|
||||||
|
public class UpdateIconEvent: PubSubEvent<string>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,22 +13,23 @@ namespace Logger
|
|||||||
{
|
{
|
||||||
public static readonly ILogger Logger = LogManager.GetLogger("InfoLogger");
|
public static readonly ILogger Logger = LogManager.GetLogger("InfoLogger");
|
||||||
public static readonly ILogger sqlLogger = LogManager.GetLogger("SqlLogger");
|
public static readonly ILogger sqlLogger = LogManager.GetLogger("SqlLogger");
|
||||||
// 日志事件,UI可以订阅
|
public static IProgress<(string message, string color,int depth)> Progress { get; set; }
|
||||||
|
static LoggerHelper()
|
||||||
public static event Action<string, string>? LogAdded;
|
{
|
||||||
|
Progress = new Progress<(string message, string color, int depth)>();
|
||||||
public static void InfoWithNotify(string message)
|
}
|
||||||
|
public static void InfoWithNotify(string message, int depth=0)
|
||||||
{
|
{
|
||||||
Logger.Info(message); // 写入 NLog
|
Logger.Info(message); // 写入 NLog
|
||||||
NotifyUI(message, "lightblue"); // 触发UI显示
|
NotifyUI(message, "blue", depth); // 触发UI显示
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SuccessWithNotify(string message)
|
public static void SuccessWithNotify(string message, int depth=0)
|
||||||
{
|
{
|
||||||
Logger.Info(message);
|
Logger.Info(message);
|
||||||
NotifyUI(message, "lightgreen");
|
NotifyUI(message, "lightgreen", depth);
|
||||||
}
|
}
|
||||||
public static void WarnWithNotify(string message, string stackTrace = null)
|
public static void WarnWithNotify(string message, string stackTrace = null, int depth = 0)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(stackTrace))
|
if (!string.IsNullOrEmpty(stackTrace))
|
||||||
{
|
{
|
||||||
@ -37,10 +38,10 @@ namespace Logger
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logger.Warn(message);
|
Logger.Warn(message);
|
||||||
NotifyUI(message, "orange");
|
NotifyUI(message, "orange", depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ErrorWithNotify(string message, string stackTrace = null)
|
public static void ErrorWithNotify(string message, string stackTrace = null, int depth = 0)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(stackTrace))
|
if (!string.IsNullOrEmpty(stackTrace))
|
||||||
{
|
{
|
||||||
@ -49,37 +50,11 @@ namespace Logger
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logger.Error(message);
|
Logger.Error(message);
|
||||||
NotifyUI(message, "red");
|
NotifyUI(message, "red", depth);
|
||||||
}
|
}
|
||||||
public static void InfoWithNotify(string message,int depth)
|
private static void NotifyUI(string message, string color, int depth)
|
||||||
{
|
{
|
||||||
Logger.Info(message); // 写入 NLog
|
Progress.Report((message, color, depth));
|
||||||
NotifyUI(message, "lightblue"); // 触发UI显示
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SuccessWithNotify(string message, int depth )
|
|
||||||
{
|
|
||||||
Logger.Info(message);
|
|
||||||
NotifyUI(message, "lightgreen");
|
|
||||||
}
|
|
||||||
public static void WarnWithNotify(string message, int depth )
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
Logger.Warn(message);
|
|
||||||
NotifyUI(message, "orange");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ErrorWithNotify(string message, int depth )
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
Logger.Error(message);
|
|
||||||
NotifyUI(message, "red");
|
|
||||||
}
|
|
||||||
private static void NotifyUI(string message, string color)
|
|
||||||
{
|
|
||||||
LogAdded?.Invoke(message,color);
|
|
||||||
}
|
}
|
||||||
// 解析堆栈,找到项目文件路径和行号
|
// 解析堆栈,找到项目文件路径和行号
|
||||||
public static string GetProjectStackLine(string stackTrace)
|
public static string GetProjectStackLine(string stackTrace)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user