添加项目文件。
This commit is contained in:
24
ADP/ADP.csproj
Normal file
24
ADP/ADP.csproj
Normal file
@@ -0,0 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Command\Command.csproj" />
|
||||
<ProjectReference Include="..\DeviceCommand\DeviceCommand.csproj" />
|
||||
<ProjectReference Include="..\LoginModule\LoginModule.csproj" />
|
||||
<ProjectReference Include="..\MainModule\MainModule.csproj" />
|
||||
<ProjectReference Include="..\MonitorModule\MonitorModule.csproj" />
|
||||
<ProjectReference Include="..\Service\Service.csproj" />
|
||||
<ProjectReference Include="..\SettingModule\SettingModule.csproj" />
|
||||
<ProjectReference Include="..\TestingModule\TestingModule.csproj" />
|
||||
<ProjectReference Include="..\UIShare\UIShare.csproj" />
|
||||
<ProjectReference Include="..\UpdateInfoMoudle\UpdateInfoMoudle.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
15
ADP/App.xaml
Normal file
15
ADP/App.xaml
Normal file
@@ -0,0 +1,15 @@
|
||||
<prism:PrismApplication x:Class="ADP.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:ADP"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:prism="http://prismlibrary.com/">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<!--自定义style-->
|
||||
<ResourceDictionary Source="/UIShare;component/Styles/CommonStyle.xaml"></ResourceDictionary>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</prism:PrismApplication>
|
||||
88
ADP/App.xaml.cs
Normal file
88
ADP/App.xaml.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using Common;
|
||||
using ADP.ViewModels;
|
||||
using ADP.ViewModels.Dialogs;
|
||||
using ADP.Views;
|
||||
using ADP.Views;
|
||||
using ADP.Views.Dialogs;
|
||||
using Logger;
|
||||
using Notifications.Wpf.Core;
|
||||
using ORM;
|
||||
using Service.Implement;
|
||||
using Service.Interface;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using UIShare.PubEvent;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using UIShare.GlobalVariable;
|
||||
using UIShare;
|
||||
|
||||
namespace ADP
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : PrismApplication
|
||||
{
|
||||
protected override Window CreateShell()
|
||||
{
|
||||
//UI线程未捕获异常处理事件
|
||||
this.DispatcherUnhandledException += OnDispatcherUnhandledException;
|
||||
//Task线程内未捕获异常处理事件
|
||||
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
|
||||
////多线程异常
|
||||
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
|
||||
return Container.Resolve<ShellView>();
|
||||
}
|
||||
private void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
LoggerHelper.Error(e.Exception.Message, e.Exception.StackTrace);
|
||||
}
|
||||
|
||||
private void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
|
||||
{
|
||||
LoggerHelper.Error(e.Exception.Message, e.Exception.StackTrace);
|
||||
}
|
||||
|
||||
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
//记录dump文件
|
||||
Exception ex = e.ExceptionObject as Exception;
|
||||
MiniDump.TryDump($"dumps\\Error_{DateTime.Now:yyyy-MM-dd HH-mm-ss-ms}.dmp", MiniDump.Option.WithFullMemory, ex);
|
||||
}
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
//初始化数据库
|
||||
//DatabaseConfig.SetTenant(10001);
|
||||
//DatabaseConfig.InitMySql("127.0.0.1",3306,"ADP","root","123456");
|
||||
//DatabaseConfig.CreateDatabaseAndCheckConnection(createDatabase: true, checkConnection: true);
|
||||
//SqlSugarContext.InitDatabase();
|
||||
//显示登录窗口
|
||||
var login = Container.Resolve<LoginModuleView>();
|
||||
var re = Container.Resolve<IRegionManager>();
|
||||
RegionManager.SetRegionManager(login, re);
|
||||
RegionManager.SetRegionManager(Application.Current.MainWindow, re);
|
||||
login.Show();
|
||||
}
|
||||
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
||||
{
|
||||
//注册弹窗
|
||||
containerRegistry.RegisterDialog<MessageBoxView, MessageBoxViewModel>("MessageBox");
|
||||
// 注册通知管理器
|
||||
INotificationManager NotificationManager = new NotificationManager();
|
||||
containerRegistry.RegisterInstance<INotificationManager>(NotificationManager);
|
||||
//注册全局变量
|
||||
containerRegistry.RegisterScoped<SystemConfig>();
|
||||
containerRegistry.RegisterScoped<StepRunning>();
|
||||
containerRegistry.RegisterScoped<ScopedContext>();
|
||||
containerRegistry.RegisterSingleton<GlobalInfo>();
|
||||
}
|
||||
//指定模块加载方式(需要手动将模块生成的dll放入Modules文件夹中)
|
||||
protected override IModuleCatalog CreateModuleCatalog()
|
||||
{
|
||||
//指定模块加载方式为从文件夹中以反射发现并加载module(推荐用法)
|
||||
return new DirectoryModuleCatalog() { ModulePath = @".\Modules" };
|
||||
}
|
||||
}
|
||||
}
|
||||
10
ADP/AssemblyInfo.cs
Normal file
10
ADP/AssemblyInfo.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
BIN
ADP/Resources/Images/error.png
Normal file
BIN
ADP/Resources/Images/error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
BIN
ADP/Resources/Images/info.png
Normal file
BIN
ADP/Resources/Images/info.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
BIN
ADP/Resources/Images/warning.png
Normal file
BIN
ADP/Resources/Images/warning.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
120
ADP/ViewModels/Dialogs/MessageBoxViewModel.cs
Normal file
120
ADP/ViewModels/Dialogs/MessageBoxViewModel.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using UIShare.PubEvent;
|
||||
using UIShare.ViewModelBase;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace ADP.ViewModels.Dialogs
|
||||
{
|
||||
public class MessageBoxViewModel : DialogViewModelBase
|
||||
{
|
||||
#region 属性
|
||||
|
||||
private string _Title;
|
||||
public string Title
|
||||
{
|
||||
get => _Title;
|
||||
set => SetProperty(ref _Title, value);
|
||||
}
|
||||
|
||||
private string _Message = "";
|
||||
public string Message
|
||||
{
|
||||
get => _Message;
|
||||
set => SetProperty(ref _Message, value);
|
||||
}
|
||||
|
||||
private string _Icon= $"pack://siteoforigin:,,,/Resources/Images/info.png";
|
||||
public string Icon
|
||||
{
|
||||
get => _Icon;
|
||||
set => SetProperty(ref _Icon, value);
|
||||
}
|
||||
|
||||
private bool _ShowYes;
|
||||
public bool ShowYes
|
||||
{
|
||||
get => _ShowYes;
|
||||
set => SetProperty(ref _ShowYes, value);
|
||||
}
|
||||
|
||||
private bool _ShowNo;
|
||||
public bool ShowNo
|
||||
{
|
||||
get => _ShowNo;
|
||||
set => SetProperty(ref _ShowNo, value);
|
||||
}
|
||||
|
||||
private bool _ShowOk;
|
||||
public bool ShowOk
|
||||
{
|
||||
get => _ShowOk;
|
||||
set => SetProperty(ref _ShowOk, value);
|
||||
}
|
||||
|
||||
private bool _ShowCancel;
|
||||
public bool ShowCancel
|
||||
{
|
||||
get => _ShowCancel;
|
||||
set => SetProperty(ref _ShowCancel, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 命令
|
||||
public ICommand YesCommand { get; set; }
|
||||
public ICommand NoCommand { get; set; }
|
||||
public ICommand OkCommand { get; set; }
|
||||
public ICommand CancelCommand { get; set; }
|
||||
#endregion
|
||||
|
||||
public DialogCloseListener RequestClose { get; set; }
|
||||
|
||||
public MessageBoxViewModel(IContainerProvider containerProvider):base(containerProvider)
|
||||
{
|
||||
YesCommand = new DelegateCommand(OnYes);
|
||||
NoCommand = new DelegateCommand(OnNo);
|
||||
OkCommand = new DelegateCommand(OnOk);
|
||||
CancelCommand = new DelegateCommand(OnCancel);
|
||||
}
|
||||
|
||||
private void CloseDialog(ButtonResult result)
|
||||
{
|
||||
var parameters = new DialogParameters();
|
||||
RequestClose.Invoke(new DialogResult(result));
|
||||
}
|
||||
|
||||
private void OnYes() => CloseDialog(ButtonResult.Yes);
|
||||
private void OnNo() => CloseDialog(ButtonResult.No);
|
||||
private void OnOk() => CloseDialog(ButtonResult.OK);
|
||||
private void OnCancel() => CloseDialog(ButtonResult.Cancel);
|
||||
|
||||
#region Prism Dialog 规范
|
||||
public bool CanCloseDialog() => true;
|
||||
|
||||
public override void OnDialogClosed()
|
||||
{
|
||||
_eventAggregator.GetEvent<OverlayEvent>().Publish(false);
|
||||
}
|
||||
|
||||
public override void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
_eventAggregator.GetEvent<OverlayEvent>().Publish(true);
|
||||
Title = parameters.GetValue<string>("Title");
|
||||
Message = parameters.GetValue<string>("Message");
|
||||
var iconKey = parameters.GetValue<string>("Icon"); // info / error / warn
|
||||
Icon = iconKey switch
|
||||
{
|
||||
"info" => $"pack://siteoforigin:,,,/Resources/Images/info.png",
|
||||
"error" => $"pack://siteoforigin:,,,/Resources/Images/error.png",
|
||||
"warn" => $"pack://siteoforigin:,,,/Resources/Images/warning.png",
|
||||
_ => $"pack://siteoforigin:,,,/Resources/Images/info.png" // 默认
|
||||
};
|
||||
|
||||
|
||||
ShowYes = parameters.GetValue<bool>("ShowYes");
|
||||
ShowNo = parameters.GetValue<bool>("ShowNo");
|
||||
ShowOk = parameters.GetValue<bool>("ShowOk");
|
||||
ShowCancel = parameters.GetValue<bool>("ShowCancel");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
772
ADP/ViewModels/ShellViewModel.cs
Normal file
772
ADP/ViewModels/ShellViewModel.cs
Normal file
@@ -0,0 +1,772 @@
|
||||
|
||||
using Logger;
|
||||
using MaterialDesignThemes.Wpf;
|
||||
using Notifications.Wpf.Core;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading; // 💡 新增:引入定时器命名空间
|
||||
using UIShare;
|
||||
using UIShare.GlobalVariable;
|
||||
using UIShare.PubEvent;
|
||||
using UIShare.UIViewModel;
|
||||
|
||||
namespace ADP.ViewModels
|
||||
{
|
||||
public class ShellViewModel : BindableBase
|
||||
{
|
||||
#region 私有字段
|
||||
private string _Title = "";
|
||||
private bool _IsLeftDrawerOpen;
|
||||
|
||||
private readonly ConcurrentDictionary<string, Task> _executionTasks = new();
|
||||
private readonly ConcurrentDictionary<string, Task> _errorExecutionTasks = new();
|
||||
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IRegionManager _regionManager;
|
||||
private readonly IContainerProvider _containerProvider;
|
||||
private readonly INotificationManager _notificationManager;
|
||||
private readonly IModuleManager _moduleManager;
|
||||
private readonly GlobalInfo _globalInfo;
|
||||
|
||||
// 💡 新增:UI 刷新定时器,用于高频让前端重新拉取当前工位的 SW 累计时间
|
||||
private readonly DispatcherTimer _uiRefreshTimer;
|
||||
#endregion
|
||||
|
||||
#region 属性
|
||||
public string Title
|
||||
{
|
||||
get => _Title;
|
||||
set => SetProperty(ref _Title, value);
|
||||
}
|
||||
public bool IsLeftDrawerOpen
|
||||
{
|
||||
get => _IsLeftDrawerOpen;
|
||||
set => SetProperty(ref _IsLeftDrawerOpen, value);
|
||||
}
|
||||
|
||||
// 代理属性:动态反映当前被激活的 Scope 状态
|
||||
public TimeSpan RunningTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CurrentContext == null) return TimeSpan.Zero;
|
||||
// 💡 核心:如果当前工位的计时器正在跑,动态累加 SW 当前的时间,否则返回其保存的固定时间值
|
||||
return CurrentContext.SW.IsRunning ? CurrentContext.SW.Elapsed : CurrentContext.RunningTime;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (CurrentContext != null && CurrentContext.RunningTime != value)
|
||||
{
|
||||
CurrentContext.RunningTime = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsTerminate
|
||||
{
|
||||
get => CurrentContext?.IsTerminate ?? false;
|
||||
set
|
||||
{
|
||||
if (CurrentContext != null && CurrentContext.IsTerminate != value)
|
||||
{
|
||||
CurrentContext.IsTerminate = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ScopedContext? CurrentContext =>
|
||||
_globalInfo.ContextDic.TryGetValue(_globalInfo.CurrentScope, out var ctx) ? ctx : null;
|
||||
private StepRunning? CurrentRunner =>
|
||||
_globalInfo.StepRunningDic.TryGetValue(_globalInfo.CurrentScope, out var runner) ? runner : null;
|
||||
|
||||
public string RunState
|
||||
{
|
||||
get => CurrentContext?.RunState ?? "运行";
|
||||
set
|
||||
{
|
||||
if (CurrentContext != null && CurrentContext.RunState != value)
|
||||
{
|
||||
CurrentContext.RunState = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool SingleStep
|
||||
{
|
||||
get => CurrentContext?.SingleStep ?? false;
|
||||
set
|
||||
{
|
||||
if (CurrentContext != null && CurrentContext.SingleStep != value)
|
||||
{
|
||||
CurrentContext.SingleStep = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PackIconKind RunIcon
|
||||
{
|
||||
get => CurrentContext?.RunIcon ?? PackIconKind.Play;
|
||||
set
|
||||
{
|
||||
if (CurrentContext != null && CurrentContext.RunIcon != value)
|
||||
{
|
||||
CurrentContext.RunIcon = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 命令
|
||||
public ICommand LeftDrawerOpenCommand { get; set; }
|
||||
public ICommand MinimizeCommand { get; set; }
|
||||
public ICommand MaximizeCommand { get; set; }
|
||||
public ICommand CloseCommand { get; set; }
|
||||
public ICommand NavigateCommand { get; set; }
|
||||
public ICommand LoadCommand { get; set; }
|
||||
public ICommand RefreshCommand { get; set; }
|
||||
public ICommand DestroyCommand { get; set; }
|
||||
public ICommand RunningCommand { get; set; }
|
||||
public ICommand RunSingleCommand { get; set; }
|
||||
public ICommand RestorationCommand { get; set; }
|
||||
public ICommand RunAbnormalStepsCommand { get; set; }
|
||||
public ICommand SaveAsCommand { get; set; }
|
||||
public ICommand SaveCommand { get; set; }
|
||||
public ICommand OpenCommand { get; set; }
|
||||
public ICommand NewCommand { get; set; }
|
||||
public ICommand SetDefaultCommand { get; set; }
|
||||
#endregion
|
||||
|
||||
public ShellViewModel(IContainerProvider containerProvider)
|
||||
{
|
||||
_containerProvider = containerProvider;
|
||||
_globalInfo = containerProvider.Resolve<GlobalInfo>();
|
||||
_eventAggregator = containerProvider.Resolve<IEventAggregator>();
|
||||
_regionManager = containerProvider.Resolve<IRegionManager>();
|
||||
_notificationManager = containerProvider.Resolve<INotificationManager>();
|
||||
_moduleManager = containerProvider.Resolve<IModuleManager>();
|
||||
|
||||
LeftDrawerOpenCommand = new DelegateCommand(LeftDrawerOpen);
|
||||
MinimizeCommand = new DelegateCommand<Window>(MinimizeWindow);
|
||||
MaximizeCommand = new DelegateCommand<Window>(MaximizeWindow);
|
||||
CloseCommand = new DelegateCommand<Window>(CloseWindow);
|
||||
NavigateCommand = new DelegateCommand<string>(Navigate);
|
||||
LoadCommand = new DelegateCommand(Load);
|
||||
RefreshCommand = new DelegateCommand(OnRefresh);
|
||||
DestroyCommand = new DelegateCommand(OnDestroy);
|
||||
RunningCommand = new DelegateCommand(OnRunning);
|
||||
RunSingleCommand = new DelegateCommand(RunSingle);
|
||||
RestorationCommand = new AsyncDelegateCommand(OnRestoration);
|
||||
RunAbnormalStepsCommand = new AsyncDelegateCommand(OnRunAbnormalSteps);
|
||||
NewCommand = new DelegateCommand(New);
|
||||
OpenCommand = new AsyncDelegateCommand<string>(Open);
|
||||
SaveAsCommand = new DelegateCommand(SaveAs);
|
||||
SaveCommand = new DelegateCommand(Save);
|
||||
SetDefaultCommand = new DelegateCommand(SetDefault);
|
||||
|
||||
_globalInfo.ContextDic.Add("default", new ScopedContext());
|
||||
|
||||
_eventAggregator.GetEvent<LoginSuccessEvent>().Subscribe(() =>
|
||||
{
|
||||
Application.Current.MainWindow.Show();
|
||||
_regionManager.RequestNavigate("ShellViewManager", "MainView");
|
||||
});
|
||||
|
||||
_eventAggregator.GetEvent<RunSingalCompletedEvent>().Subscribe(UpdateRunIcon);
|
||||
|
||||
_globalInfo.ScopeChanged += (s, e) =>
|
||||
{
|
||||
RefreshAllContextProperties();
|
||||
};
|
||||
|
||||
// 💡 初始化轻量级 UI 定时器:每 100 毫秒刷新一次当前可见工位的界面时间
|
||||
_uiRefreshTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) };
|
||||
_uiRefreshTimer.Tick += (s, e) => RaisePropertyChanged(nameof(RunningTime));
|
||||
_uiRefreshTimer.Start();
|
||||
}
|
||||
|
||||
private void RefreshAllContextProperties()
|
||||
{
|
||||
RaisePropertyChanged(nameof(RunState));
|
||||
RaisePropertyChanged(nameof(SingleStep));
|
||||
RaisePropertyChanged(nameof(RunIcon));
|
||||
RaisePropertyChanged(nameof(RunningTime));
|
||||
RaisePropertyChanged(nameof(IsTerminate));
|
||||
}
|
||||
|
||||
#region 命令处理与事件
|
||||
private async void OnRunning()
|
||||
{
|
||||
string runningScope = _globalInfo.CurrentScope;
|
||||
ScopedContext? targetContext = CurrentContext;
|
||||
StepRunning? targetRunner = CurrentRunner;
|
||||
|
||||
if (runningScope == "default" || string.IsNullOrEmpty(runningScope) || targetContext == null || targetRunner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetContext.RunState == "运行")
|
||||
{
|
||||
targetContext.SingleStep = false;
|
||||
LoggerHelper.InfoWithNotify($"{_globalInfo.UserName} 执行工位 [{runningScope}] 运行命令");
|
||||
|
||||
targetContext.RunState = "暂停";
|
||||
targetContext.RunIcon = PackIconKind.Pause;
|
||||
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
|
||||
if (targetContext.IsStop == null)
|
||||
{
|
||||
targetContext.IsStop = false;
|
||||
|
||||
// 💡 启动或恢复:启动属于该快照工位独立的 SW 计时器
|
||||
targetContext.SW.Start();
|
||||
|
||||
if (!_executionTasks.TryGetValue(runningScope, out var existingTask) || existingTask == null)
|
||||
{
|
||||
existingTask = targetRunner.ExecuteSteps(targetContext.Program, cancellationToken: targetRunner.stepCTS.Token);
|
||||
_executionTasks[runningScope] = existingTask;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await existingTask;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.ErrorWithNotify($"工位 [{runningScope}] 异常中止: {ex.Message}");
|
||||
}
|
||||
|
||||
// 💡 测试正常完毕或取消:停止当前工位的 SW,并将最终时间固化到 RunningTime 字段中
|
||||
targetContext.SW.Stop();
|
||||
targetContext.RunningTime = targetContext.SW.Elapsed;
|
||||
|
||||
targetContext.RunState = "运行";
|
||||
targetContext.RunIcon = PackIconKind.Play;
|
||||
targetContext.IsStop = null;
|
||||
|
||||
if (targetRunner.stepCTS.IsCancellationRequested)
|
||||
{
|
||||
targetRunner.stepCTS = new CancellationTokenSource();
|
||||
_executionTasks.TryRemove(runningScope, out _);
|
||||
}
|
||||
else if (_executionTasks.TryGetValue(runningScope, out var currentTask) && currentTask != null && currentTask.IsCompleted)
|
||||
{
|
||||
targetContext.IsTerminate = true;
|
||||
_executionTasks.TryRemove(runningScope, out _);
|
||||
}
|
||||
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
}
|
||||
else if (targetContext.IsStop == true)
|
||||
{
|
||||
targetContext.IsStop = false;
|
||||
// 💡 从暂停中恢复,继续累加当前工位计时
|
||||
targetContext.SW.Start();
|
||||
}
|
||||
}
|
||||
else // 用户点击了暂停
|
||||
{
|
||||
LoggerHelper.InfoWithNotify($"{_globalInfo.UserName} 点击工位 [{runningScope}] 暂停命令");
|
||||
targetContext.SingleStep = true;
|
||||
targetContext.IsStop = true;
|
||||
targetContext.RunState = "运行";
|
||||
targetContext.RunIcon = PackIconKind.Play;
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private async void RunSingle()
|
||||
{
|
||||
string runningScope = _globalInfo.CurrentScope;
|
||||
ScopedContext? targetContext = CurrentContext;
|
||||
StepRunning? targetRunner = CurrentRunner;
|
||||
|
||||
if (runningScope == "default" || string.IsNullOrEmpty(runningScope) || targetContext == null || targetRunner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetContext.RunState == "运行")
|
||||
{
|
||||
targetContext.SingleStep = true;
|
||||
LoggerHelper.InfoWithNotify($"{_globalInfo.UserName} 执行工位 [{runningScope}] 单步执行命令");
|
||||
|
||||
targetContext.RunState = "暂停";
|
||||
targetContext.RunIcon = PackIconKind.Pause;
|
||||
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
|
||||
if (targetContext.IsStop == null)
|
||||
{
|
||||
targetContext.IsStop = false;
|
||||
|
||||
// 💡 单步启动:让专属工位的 SW 跑起来
|
||||
targetContext.SW.Start();
|
||||
|
||||
if (!_executionTasks.TryGetValue(runningScope, out var existingTask) || existingTask == null)
|
||||
{
|
||||
existingTask = targetRunner.ExecuteSteps(targetContext.Program, cancellationToken: targetRunner.stepCTS.Token);
|
||||
_executionTasks[runningScope] = existingTask;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await existingTask;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.ErrorWithNotify($"工位 [{runningScope}] 单步执行异常: {ex.Message}");
|
||||
}
|
||||
|
||||
// 💡 单步单步完成后会被 StepRunning 挂起,在此暂时停止 SW
|
||||
targetContext.SW.Stop();
|
||||
targetContext.RunningTime = targetContext.SW.Elapsed;
|
||||
|
||||
targetContext.RunState = "运行";
|
||||
targetContext.RunIcon = PackIconKind.Play;
|
||||
targetContext.IsStop = null;
|
||||
|
||||
if (targetRunner.stepCTS.IsCancellationRequested)
|
||||
{
|
||||
targetRunner.stepCTS = new CancellationTokenSource();
|
||||
_executionTasks.TryRemove(runningScope, out _);
|
||||
}
|
||||
else if (_executionTasks.TryGetValue(runningScope, out var currentTask) && currentTask != null && currentTask.IsCompleted)
|
||||
{
|
||||
targetContext.IsTerminate = true;
|
||||
_executionTasks.TryRemove(runningScope, out _);
|
||||
}
|
||||
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
}
|
||||
else if (targetContext.IsStop == true)
|
||||
{
|
||||
targetContext.IsStop = false;
|
||||
// 💡 继续单步,继续计时
|
||||
targetContext.SW.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnRestoration()
|
||||
{
|
||||
string runningScope = _globalInfo.CurrentScope;
|
||||
ScopedContext? targetContext = CurrentContext;
|
||||
StepRunning? targetRunner = CurrentRunner;
|
||||
|
||||
if (runningScope == "default" || string.IsNullOrEmpty(runningScope) || targetContext == null || targetRunner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LoggerHelper.InfoWithNotify($"{_globalInfo.UserName} 执行工位 [{runningScope}] 复位命令");
|
||||
|
||||
_executionTasks.TryGetValue(runningScope, out var currentTask);
|
||||
_errorExecutionTasks.TryGetValue(runningScope, out var errorTask);
|
||||
|
||||
if (currentTask != null || errorTask != null)
|
||||
{
|
||||
targetRunner.stepCTS.Cancel();
|
||||
targetRunner.errorStepCTS.Cancel();
|
||||
|
||||
await Task.Delay(200);
|
||||
|
||||
// 💡 彻底复位:停止当前工位的计时器,并且完全归零(Reset)
|
||||
targetContext.SW.Reset();
|
||||
targetContext.RunningTime = TimeSpan.Zero;
|
||||
|
||||
targetContext.IsStop = null;
|
||||
targetRunner.ResetAllStepStatus(targetContext.Program.StepCollection);
|
||||
targetRunner.ResetAllStepStatus(targetContext.Program.ErrorStepCollection);
|
||||
targetContext.IsTerminate = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetRunner.stepCTS = new CancellationTokenSource();
|
||||
targetRunner.errorStepCTS = new CancellationTokenSource();
|
||||
|
||||
// 💡 无任务状态下的直接归零
|
||||
targetContext.SW.Reset();
|
||||
targetContext.RunningTime = TimeSpan.Zero;
|
||||
|
||||
targetContext.IsStop = null;
|
||||
targetRunner.ResetAllStepStatus(targetContext.Program.StepCollection);
|
||||
targetRunner.ResetAllStepStatus(targetContext.Program.ErrorStepCollection);
|
||||
targetContext.IsTerminate = false;
|
||||
}
|
||||
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
}
|
||||
|
||||
private async Task OnRunAbnormalSteps()
|
||||
{
|
||||
string runningScope = _globalInfo.CurrentScope;
|
||||
ScopedContext? targetContext = CurrentContext;
|
||||
StepRunning? targetRunner = CurrentRunner;
|
||||
|
||||
if (runningScope == "default" || string.IsNullOrEmpty(runningScope) || targetContext == null || targetRunner == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LoggerHelper.InfoWithNotify($"{_globalInfo.UserName} 执行工位 [{runningScope}] 异常流程命令");
|
||||
|
||||
// 💡 异常测试启动计时
|
||||
targetContext.SW.Start();
|
||||
|
||||
if (!_errorExecutionTasks.TryGetValue(runningScope, out var existingErrorTask) || existingErrorTask == null)
|
||||
{
|
||||
existingErrorTask = targetRunner.ExecuteErrorSteps(targetContext.Program, cancellationToken: targetRunner.errorStepCTS.Token);
|
||||
_errorExecutionTasks[runningScope] = existingErrorTask;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await existingErrorTask;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.ErrorWithNotify($"工位 [{runningScope}] 异常流程执行出错: {ex.Message}");
|
||||
}
|
||||
|
||||
// 💡 异常测试结束停止计时
|
||||
targetContext.SW.Stop();
|
||||
targetContext.RunningTime = targetContext.SW.Elapsed;
|
||||
|
||||
if (targetRunner.errorStepCTS.IsCancellationRequested)
|
||||
{
|
||||
targetRunner.errorStepCTS = new CancellationTokenSource();
|
||||
_errorExecutionTasks.TryRemove(runningScope, out _);
|
||||
}
|
||||
else if (_errorExecutionTasks.TryGetValue(runningScope, out var currentErrorTask) && currentErrorTask != null && currentErrorTask.IsCompleted)
|
||||
{
|
||||
targetContext.IsTerminate = true;
|
||||
_errorExecutionTasks.TryRemove(runningScope, out _);
|
||||
}
|
||||
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
}
|
||||
|
||||
private void SetDefault()
|
||||
{
|
||||
// 💡 1. 抓取触发瞬间的 Scope 与 Context 快照
|
||||
string runningScope = _globalInfo.CurrentScope;
|
||||
ScopedContext? targetContext = CurrentContext;
|
||||
|
||||
if (runningScope == "default" || string.IsNullOrEmpty(runningScope) || targetContext == null) return;
|
||||
|
||||
if (targetContext.CurrentFilePath != null)
|
||||
{
|
||||
//SystemConfig.DefaultProgramFilePath = targetContext.CurrentFilePath;
|
||||
//ConfigService.Save();
|
||||
LoggerHelper.SuccessWithNotify($"工位 [{runningScope}] 已成功将当前程序设为默认启动程序");
|
||||
}
|
||||
}
|
||||
|
||||
private void New()
|
||||
{
|
||||
// 💡 1. 抓取快照
|
||||
string runningScope = _globalInfo.CurrentScope;
|
||||
ScopedContext? targetContext = CurrentContext;
|
||||
|
||||
if (runningScope == "default" || string.IsNullOrEmpty(runningScope) || targetContext == null) return;
|
||||
|
||||
// 💡 2. 严格对快照隔离的 Context 数据进行清理,不影响其他工位
|
||||
targetContext.CurrentFilePath = null;
|
||||
targetContext.Program.Parameters.Clear();
|
||||
targetContext.Program.StepCollection.Clear();
|
||||
targetContext.Program.ErrorStepCollection.Clear();
|
||||
|
||||
LoggerHelper.InfoWithNotify($"工位 [{runningScope}] 创建了空程序文件");
|
||||
|
||||
// 如果当前正看着该工位,刷新 UI 显示
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
}
|
||||
|
||||
private async Task Open(string filePath = null)
|
||||
{
|
||||
// 💡 1. 抓取进方法瞬间的快照,锁死上下文
|
||||
string runningScope = _globalInfo.CurrentScope;
|
||||
ScopedContext? targetContext = CurrentContext;
|
||||
|
||||
if (runningScope == "default" || string.IsNullOrEmpty(runningScope) || targetContext == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
// 如果没有传路径,弹出文件选择对话框(WPF 对话框是模态的,会阻塞当前 UI 线程)
|
||||
if (string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
var openFileDialog = new Microsoft.Win32.OpenFileDialog
|
||||
{
|
||||
Filter = "ADP程序文件|*.ADP|所有文件|*.*",
|
||||
Title = $"工位 [{runningScope}] 打开程序",
|
||||
};
|
||||
|
||||
if (openFileDialog.ShowDialog() != true)
|
||||
return; // 用户取消选择
|
||||
|
||||
filePath = openFileDialog.FileName;
|
||||
}
|
||||
|
||||
// 确认文件存在
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
LoggerHelper.ErrorWithNotify($"文件不存在: {filePath}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 读取 JSON 文件
|
||||
string json = File.ReadAllText(filePath);
|
||||
|
||||
// 反序列化为 ProgramModel
|
||||
var program = Newtonsoft.Json.JsonConvert.DeserializeObject<ProgramModel>(json);
|
||||
|
||||
if (program == null)
|
||||
{
|
||||
LoggerHelper.WarnWithNotify($"文件格式不正确或为空: {filePath}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 💡 2. 严格赋值给快照锁定下的当前工位上下文,实现数据完全隔离
|
||||
targetContext.Program.Parameters = program.Parameters;
|
||||
targetContext.Program.StepCollection = program.StepCollection;
|
||||
targetContext.Program.ErrorStepCollection = program.ErrorStepCollection;
|
||||
targetContext.CurrentFilePath = filePath;
|
||||
|
||||
LoggerHelper.SuccessWithNotify($"工位 [{runningScope}] 成功打开文件: {filePath}");
|
||||
|
||||
// 💡 3. 安全调用异步复位,确保重置的是对应工位的数据
|
||||
// 注意:由于在 OnRestoration 内部第一行也做了快照拦截,
|
||||
// 如果用户此时正好在看这个工位,它会自动完美执行
|
||||
await OnRestoration();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.ErrorWithNotify($"工位 [{runningScope}] 打开文件失败: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 💡 4. 异步回归:不管中途用户切去了哪里,回到该工位时及时刷新显示
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveAs()
|
||||
{
|
||||
if (!_globalInfo.IsAdmin) return;
|
||||
|
||||
// 💡 1. 抓取快照
|
||||
string runningScope = _globalInfo.CurrentScope;
|
||||
ScopedContext? targetContext = CurrentContext;
|
||||
|
||||
if (runningScope == "default" || string.IsNullOrEmpty(runningScope) || targetContext == null) return;
|
||||
|
||||
string defaultPath = @"D:\ADP\子程序";
|
||||
if (!Directory.Exists(defaultPath))
|
||||
Directory.CreateDirectory(defaultPath);
|
||||
|
||||
var saveFileDialog = new Microsoft.Win32.SaveFileDialog
|
||||
{
|
||||
Filter = "ADP程序文件|*.adp|所有文件|*.*",
|
||||
Title = $"工位 [{runningScope}] 程序另存为",
|
||||
FileName = "NewProgram.ADP",
|
||||
InitialDirectory = defaultPath
|
||||
};
|
||||
|
||||
if (saveFileDialog.ShowDialog() == true)
|
||||
{
|
||||
// 💡 2. 将新路径安全写入快照工位
|
||||
targetContext.CurrentFilePath = saveFileDialog.FileName;
|
||||
|
||||
// 💡 3. 调用你的底层文件保存逻辑,传入快照工位的 Program 模型
|
||||
SaveProgramToFile(targetContext.CurrentFilePath, targetContext.Program);
|
||||
|
||||
LoggerHelper.InfoWithNotify($"{_globalInfo.UserName} 另存为文件成功: {saveFileDialog.FileName}");
|
||||
|
||||
if (_globalInfo.CurrentScope == runningScope) RefreshAllContextProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private void Save()
|
||||
{
|
||||
if (!_globalInfo.IsAdmin) return;
|
||||
|
||||
// 💡 1. 抓取快照
|
||||
string runningScope = _globalInfo.CurrentScope;
|
||||
ScopedContext? targetContext = CurrentContext;
|
||||
|
||||
if (runningScope == "default" || string.IsNullOrEmpty(runningScope) || targetContext == null) return;
|
||||
|
||||
// 💡 2. 判断当前工位是否有历史路径
|
||||
if (targetContext.CurrentFilePath == null)
|
||||
{
|
||||
SaveAs();
|
||||
return;
|
||||
}
|
||||
|
||||
// 💡 3. 持久化当前快照工位的 Program
|
||||
SaveProgramToFile(targetContext.CurrentFilePath, targetContext.Program);
|
||||
LoggerHelper.SuccessWithNotify($"工位 [{runningScope}] 程序保存成功!");
|
||||
}
|
||||
|
||||
// 💡 辅助方法:建议将你的通用序列化落盘代码调整为接收 ProgramModel 参数,提高复用性
|
||||
private void SaveProgramToFile(string filePath, ProgramModel programModel)
|
||||
{
|
||||
try
|
||||
{
|
||||
string json = Newtonsoft.Json.JsonConvert.SerializeObject(programModel, Newtonsoft.Json.Formatting.Indented);
|
||||
File.WriteAllText(filePath, json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.ErrorWithNotify($"写入程序文件失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateRunIcon(string obj)
|
||||
{
|
||||
CurrentContext?.SW.Stop();
|
||||
CurrentContext.RunningTime = CurrentContext.SW.Elapsed;
|
||||
RunIcon = obj switch
|
||||
{
|
||||
"Play" => PackIconKind.Play,
|
||||
"Pause" => PackIconKind.Pause,
|
||||
_ => RunIcon
|
||||
};
|
||||
}
|
||||
|
||||
private void OnRefresh()
|
||||
{
|
||||
_eventAggregator.GetEvent<ExpandViewEvent>().Publish("");
|
||||
_globalInfo.CurrentScope = "default";
|
||||
}
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_globalInfo.CurrentScope == "default" || string.IsNullOrEmpty(_globalInfo.CurrentScope)) return;
|
||||
|
||||
string targetRegionName = _globalInfo.CurrentScope;
|
||||
|
||||
// 💡 物理销毁工位时,顺便清理任务字典,防止内存泄漏
|
||||
_executionTasks.TryRemove(targetRegionName, out _);
|
||||
_errorExecutionTasks.TryRemove(targetRegionName, out _);
|
||||
|
||||
if (_regionManager.Regions.ContainsRegionWithName(targetRegionName))
|
||||
{
|
||||
var region = _regionManager.Regions[targetRegionName];
|
||||
var viewsToDestroy = region.Views.ToList();
|
||||
|
||||
foreach (var view in viewsToDestroy)
|
||||
{
|
||||
if (view is FrameworkElement element)
|
||||
{
|
||||
var viewModel = element.DataContext;
|
||||
region.Remove(view);
|
||||
if (viewModel is IDisposable disposableVM) disposableVM.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_globalInfo.ContextDic.Remove(targetRegionName);
|
||||
_globalInfo.StepRunningDic.Remove(targetRegionName);
|
||||
|
||||
var parameters = new NavigationParameters { { "Name", targetRegionName } };
|
||||
_regionManager.RequestNavigate(targetRegionName, "ProtocolStartView", parameters);
|
||||
_eventAggregator.GetEvent<ExpandViewEvent>().Publish("");
|
||||
}
|
||||
private void Load()
|
||||
{
|
||||
_notificationManager.ShowAsync(new NotificationContent { Title = "登录成功", Message = "", Type = NotificationType.Success });
|
||||
//默认导航到主界面
|
||||
Type moduleAType = typeof(MainModule.MainModule);
|
||||
_moduleManager.LoadModule(moduleAType.Name);
|
||||
}
|
||||
private void Navigate(string content)
|
||||
{
|
||||
switch (content)
|
||||
{
|
||||
case "主界面":
|
||||
if (_globalInfo.CurrentScope == "default" || string.IsNullOrEmpty(_globalInfo.CurrentScope))
|
||||
{
|
||||
_regionManager.RequestNavigate("ShellViewManager", "MainView");
|
||||
break;
|
||||
}
|
||||
var TestingRegion = _globalInfo.CurrentScope;
|
||||
if (!_regionManager.Regions.ContainsRegionWithName(TestingRegion)) break;
|
||||
_regionManager.RequestNavigate(TestingRegion, "AutomatedTestingView");
|
||||
break;
|
||||
case "监控界面":
|
||||
// 仅当某个工位被选中(九宫格已展开/选择)时才跳转,默认 default 跳过。
|
||||
if (_globalInfo.CurrentScope == "default" || string.IsNullOrEmpty(_globalInfo.CurrentScope)) break;
|
||||
|
||||
// 记录界面不是填到全局的 ShellViewManager,而是填到该工位专属的 region。
|
||||
var monitorRegion = _globalInfo.CurrentScope;
|
||||
if (!_regionManager.Regions.ContainsRegionWithName(monitorRegion)) break;
|
||||
|
||||
var monitorParameters = new NavigationParameters { { "Name", monitorRegion } };
|
||||
_regionManager.RequestNavigate(monitorRegion, "MonitorView", monitorParameters);
|
||||
IsLeftDrawerOpen = false;
|
||||
break;
|
||||
case "记录界面":
|
||||
if (_globalInfo.CurrentScope == "default" || string.IsNullOrEmpty(_globalInfo.CurrentScope)) break;
|
||||
|
||||
// 记录界面不是填到全局的 ShellViewManager,而是填到该工位专属的 region。
|
||||
var recordRegion = _globalInfo.CurrentScope;
|
||||
if (!_regionManager.Regions.ContainsRegionWithName(recordRegion)) break;
|
||||
|
||||
var recordParameters = new NavigationParameters { { "Name", recordRegion } };
|
||||
_regionManager.RequestNavigate(recordRegion, "RecordView", recordParameters);
|
||||
IsLeftDrawerOpen = false;
|
||||
break;
|
||||
case "设置界面":
|
||||
if (_globalInfo.CurrentScope == "default" || string.IsNullOrEmpty(_globalInfo.CurrentScope)) break;
|
||||
|
||||
// 记录界面不是填到全局的 ShellViewManager,而是填到该工位专属的 region。
|
||||
var settingRegion = _globalInfo.CurrentScope;
|
||||
if (!_regionManager.Regions.ContainsRegionWithName(settingRegion)) break;
|
||||
|
||||
var settingParameters = new NavigationParameters { { "Name", settingRegion } };
|
||||
_regionManager.RequestNavigate(settingRegion, "SettingView", settingParameters);
|
||||
IsLeftDrawerOpen = false;
|
||||
break;
|
||||
case "更新界面":
|
||||
_regionManager.RequestNavigate("ShellViewManager", "UpdateInfoView");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void LeftDrawerOpen()
|
||||
{
|
||||
IsLeftDrawerOpen = true;
|
||||
}
|
||||
|
||||
private void MinimizeWindow(Window window)
|
||||
{
|
||||
if (window != null)
|
||||
window.WindowState = WindowState.Minimized;
|
||||
}
|
||||
|
||||
private void MaximizeWindow(Window window)
|
||||
{
|
||||
if (window != null)
|
||||
{
|
||||
window.WindowState = window.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseWindow(Window window)
|
||||
{
|
||||
window?.Close();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
87
ADP/Views/Dialogs/MessageBoxView.xaml
Normal file
87
ADP/Views/Dialogs/MessageBoxView.xaml
Normal file
@@ -0,0 +1,87 @@
|
||||
<UserControl x:Class="ADP.Views.Dialogs.MessageBoxView"
|
||||
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:ADP.Views.Dialogs"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
mc:Ignorable="d"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
Background="Transparent"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
Height="250"
|
||||
Width="300">
|
||||
<prism:Dialog.WindowStyle>
|
||||
<Style BasedOn="{StaticResource DialogUserManageStyle}"
|
||||
TargetType="Window" />
|
||||
</prism:Dialog.WindowStyle>
|
||||
<Border CornerRadius="20"
|
||||
Background="white"
|
||||
MouseLeftButtonDown="Border_MouseLeftButtonDown">
|
||||
<Grid Background="Transparent">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
|
||||
<!-- Title -->
|
||||
<TextBlock Grid.Row="0"
|
||||
Margin="15 5 5 5"
|
||||
FontSize="18"
|
||||
FontWeight="Bold"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Title}"
|
||||
Foreground="#333" />
|
||||
|
||||
<StackPanel HorizontalAlignment="Center"
|
||||
Grid.Row="1">
|
||||
<!-- Icon -->
|
||||
<Image
|
||||
Width="100"
|
||||
Height="100"
|
||||
VerticalAlignment="Top"
|
||||
Margin="5 15 0 0"
|
||||
Source="{Binding Icon}" />
|
||||
<!-- Message -->
|
||||
<TextBlock
|
||||
FontSize="20"
|
||||
Margin="15 0 0 0"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap"
|
||||
Text="{Binding Message}" />
|
||||
</StackPanel>
|
||||
<!-- Buttons -->
|
||||
<StackPanel Grid.Row="2"
|
||||
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Right">
|
||||
|
||||
<Button Content="Yes"
|
||||
Width="80"
|
||||
Margin="10 10"
|
||||
Visibility="{Binding ShowYes, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Command="{Binding YesCommand}" />
|
||||
|
||||
<Button Content="No"
|
||||
Width="80"
|
||||
Margin="10 10"
|
||||
Visibility="{Binding ShowNo, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Command="{Binding NoCommand}" />
|
||||
|
||||
<Button Content="OK"
|
||||
Width="80"
|
||||
Margin="10 10"
|
||||
Visibility="{Binding ShowOk, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Command="{Binding OkCommand}" />
|
||||
|
||||
<Button Content="Cancel"
|
||||
Width="80"
|
||||
Margin="10 10"
|
||||
Visibility="{Binding ShowCancel, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Command="{Binding CancelCommand}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
36
ADP/Views/Dialogs/MessageBoxView.xaml.cs
Normal file
36
ADP/Views/Dialogs/MessageBoxView.xaml.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
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 ADP.Views.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// MessageBoxView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class MessageBoxView : UserControl
|
||||
{
|
||||
public MessageBoxView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
Window.GetWindow(this)?.DragMove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
21
ADP/Views/LoginModuleView.xaml
Normal file
21
ADP/Views/LoginModuleView.xaml
Normal file
@@ -0,0 +1,21 @@
|
||||
<mah:MetroWindow xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:helpers="clr-namespace:UIShare.Helpers;assembly=UIShare"
|
||||
x:Class="ADP.Views.LoginModuleView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
xmlns:local="clr-namespace:ADP.Views"
|
||||
mc:Ignorable="d"
|
||||
Title="ADP"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Height="315"
|
||||
Width="420"
|
||||
ResizeMode="NoResize">
|
||||
<Grid>
|
||||
<ContentControl prism:RegionManager.RegionName="LoginRegion" />
|
||||
</Grid>
|
||||
</mah:MetroWindow>
|
||||
38
ADP/Views/LoginModuleView.xaml.cs
Normal file
38
ADP/Views/LoginModuleView.xaml.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using UIShare.PubEvent;
|
||||
using MahApps.Metro.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
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.Shapes;
|
||||
using Path = System.IO.Path;
|
||||
|
||||
namespace ADP.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Login.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class LoginModuleView : MetroWindow
|
||||
{
|
||||
public LoginModuleView(IEventAggregator eventAggregator)
|
||||
{
|
||||
InitializeComponent();
|
||||
//订阅登录成功事件
|
||||
eventAggregator.GetEvent<LoginSuccessEvent>().Subscribe(() =>
|
||||
{
|
||||
this.Close();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
339
ADP/Views/ShellView.xaml
Normal file
339
ADP/Views/ShellView.xaml
Normal file
@@ -0,0 +1,339 @@
|
||||
<Window x:Class="ADP.Views.ShellView"
|
||||
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:converter="clr-namespace:UIShare.Converters;assembly=UIShare"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Topmost="false"
|
||||
mc:Ignorable="d"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
WindowStyle="None"
|
||||
WindowState="Maximized"
|
||||
Title="ShellView"
|
||||
d:DesignHeight="1080"
|
||||
d:DesignWidth="1920">
|
||||
<WindowChrome.WindowChrome>
|
||||
<WindowChrome GlassFrameThickness="-1" />
|
||||
</WindowChrome.WindowChrome>
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Loaded">
|
||||
<i:InvokeCommandAction Command="{Binding LoadCommand}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
<Window.Resources>
|
||||
<converter:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||
<converter:TimeSpanToStringConverter x:Key="TimeSpanConverter" />
|
||||
</Window.Resources>
|
||||
<materialDesign:DrawerHost x:Name="MainDrawerHost"
|
||||
IsLeftDrawerOpen="{Binding IsLeftDrawerOpen, Mode=TwoWay}">
|
||||
|
||||
<!-- ✅ 左侧抽屉内容 -->
|
||||
<materialDesign:DrawerHost.LeftDrawerContent>
|
||||
<StackPanel Width="220"
|
||||
Background="{DynamicResource MaterialDesignPaper}">
|
||||
<TextBlock Text="导航菜单"
|
||||
FontSize="18"
|
||||
Margin="16"
|
||||
Foreground="{DynamicResource PrimaryHueMidBrush}" />
|
||||
<Separator Margin="0,0,0,8" />
|
||||
<Button Content="主界面"
|
||||
Command="{Binding NavigateCommand}"
|
||||
CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"
|
||||
Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Margin="8" />
|
||||
<Button Content="监控界面"
|
||||
Command="{Binding NavigateCommand}"
|
||||
CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"
|
||||
Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Margin="8" />
|
||||
<Button Content="记录界面"
|
||||
Command="{Binding NavigateCommand}"
|
||||
CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"
|
||||
Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Margin="8" />
|
||||
<Button Content="设置界面"
|
||||
Command="{Binding NavigateCommand}"
|
||||
CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"
|
||||
Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Margin="8" />
|
||||
<Button Content="更新界面"
|
||||
Command="{Binding NavigateCommand}"
|
||||
CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"
|
||||
Style="{StaticResource MaterialDesignFlatButton}"
|
||||
Margin="8" />
|
||||
</StackPanel>
|
||||
</materialDesign:DrawerHost.LeftDrawerContent>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<!-- 顶部工具栏 -->
|
||||
<materialDesign:ColorZone Mode="PrimaryMid"
|
||||
MouseLeftButtonDown="ColorZone_MouseLeftButtonDown">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Menu Grid.Column="0"
|
||||
Background="Transparent"
|
||||
Foreground="White"
|
||||
VerticalAlignment="Center">
|
||||
<!-- 文件菜单 -->
|
||||
<MenuItem FontSize="13"
|
||||
Height="50"
|
||||
Header="菜单"
|
||||
Foreground="White"
|
||||
Command="{Binding DataContext.LeftDrawerOpenCommand, RelativeSource={RelativeSource AncestorType=Window}}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Menu"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
||||
|
||||
<!-- 工具菜单 -->
|
||||
<MenuItem Header="工具"
|
||||
FontSize="13"
|
||||
Height="50"
|
||||
Foreground="White">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Tools"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
|
||||
<!-- 新建 -->
|
||||
<MenuItem Header="新建"
|
||||
Foreground="Black"
|
||||
Command="{Binding NewCommand}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="FilePlus"
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
||||
<!-- 打开 -->
|
||||
<MenuItem Header="打开"
|
||||
Foreground="Black"
|
||||
Command="{Binding OpenCommand}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="FolderOpen"
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
||||
<!-- 保存 -->
|
||||
<MenuItem Header="保存"
|
||||
Foreground="Black"
|
||||
Command="{Binding SaveCommand}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="ContentSave"
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
||||
<!-- 另存为 -->
|
||||
<MenuItem Header="另存为"
|
||||
Foreground="Black"
|
||||
Command="{Binding SaveAsCommand}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="ContentSaveEdit"
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
||||
<!-- 设置默认程序 -->
|
||||
<MenuItem Header="设置默认程序"
|
||||
Foreground="Black"
|
||||
Command="{Binding SetDefaultCommand}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Cog"
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
||||
<!-- 蜂鸣器消音 -->
|
||||
<MenuItem Header="蜂鸣器消音"
|
||||
FontSize="14"
|
||||
Height="50"
|
||||
Foreground="Black"
|
||||
Command="{Binding SilenceBuzzerCommand}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="BellOff"
|
||||
Foreground="Black" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem Header="切换九宫格"
|
||||
FontSize="13"
|
||||
Height="50"
|
||||
Foreground="White"
|
||||
Command="{Binding RefreshCommand}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Refresh"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="销毁作用域"
|
||||
FontSize="13"
|
||||
Height="50"
|
||||
Foreground="White"
|
||||
Command="{Binding DestroyCommand}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Death"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem FontSize="14"
|
||||
Height="50"
|
||||
Header="运行"
|
||||
IsEnabled="{Binding IsTerminate, Converter={StaticResource InverseBooleanConverter}}"
|
||||
Command="{Binding RunningCommand}"
|
||||
Foreground="White">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="{Binding RunIcon}"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem FontSize="14"
|
||||
Height="50"
|
||||
Header="单步执行"
|
||||
IsEnabled="{Binding IsTerminate, Converter={StaticResource InverseBooleanConverter}}"
|
||||
Command="{Binding RunSingleCommand}"
|
||||
Foreground="White">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="ArrowRight"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem FontSize="14"
|
||||
Height="50"
|
||||
Header="异常流程"
|
||||
Command="{Binding RunAbnormalStepsCommand}"
|
||||
IsEnabled="{Binding IsTerminate, Converter={StaticResource InverseBooleanConverter}}"
|
||||
Foreground="White">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="AlertCircle"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem FontSize="14"
|
||||
Height="50"
|
||||
Header="复位"
|
||||
Command="{Binding RestorationCommand}"
|
||||
Foreground="White">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Restart"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem FontSize="14"
|
||||
Height="50"
|
||||
Foreground="White">
|
||||
<MenuItem.Header>
|
||||
<TextBlock>
|
||||
<Run Text="运行时间:" />
|
||||
<TextBlock Text="{Binding RunningTime, Converter={StaticResource TimeSpanConverter}}" />
|
||||
</TextBlock>
|
||||
</MenuItem.Header>
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Clock"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
<Menu Grid.Column="2"
|
||||
Margin="0 0 20 0">
|
||||
<MenuItem FontSize="13"
|
||||
Height="50"
|
||||
Header="最小化"
|
||||
Foreground="White"
|
||||
Command="{Binding MinimizeCommand}"
|
||||
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Minimize"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
|
||||
<!--<MenuItem FontSize="13"
|
||||
Height="50"
|
||||
Header="最大化"
|
||||
Foreground="White"
|
||||
Command="{Binding MaximizeCommand}"
|
||||
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Maximize"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>-->
|
||||
|
||||
<MenuItem FontSize="13"
|
||||
Height="50"
|
||||
Header="关闭"
|
||||
Foreground="White"
|
||||
Command="{Binding CloseCommand}"
|
||||
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}">
|
||||
<MenuItem.Icon>
|
||||
<materialDesign:PackIcon Kind="Close"
|
||||
Foreground="White" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
</Grid>
|
||||
<!-- 左侧菜单 -->
|
||||
|
||||
|
||||
|
||||
</materialDesign:ColorZone>
|
||||
|
||||
<materialDesign:DialogHost Grid.Row="1"
|
||||
x:Name="DialogHost"
|
||||
DialogBackground="Transparent"
|
||||
Background="Transparent"
|
||||
Identifier="Root">
|
||||
<!-- 主内容区 -->
|
||||
<Grid>
|
||||
<ContentControl prism:RegionManager.RegionName="ShellViewManager" />
|
||||
<Border x:Name="Overlay"
|
||||
Background="#40000000"
|
||||
Visibility="Collapsed"
|
||||
Panel.ZIndex="1">
|
||||
<StackPanel Width="150"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0 0 0 100">
|
||||
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Border x:Name="Waitinglay"
|
||||
Background="#40000000"
|
||||
Visibility="Collapsed"
|
||||
Panel.ZIndex="1">
|
||||
<StackPanel Width="150"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0 0 0 100">
|
||||
<ProgressBar Width="80"
|
||||
Height="80"
|
||||
Margin="20"
|
||||
IsIndeterminate="True"
|
||||
Style="{StaticResource MaterialDesignCircularProgressBar}" />
|
||||
<TextBlock FontSize="30"
|
||||
Text="加载中......"
|
||||
HorizontalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</materialDesign:DialogHost>
|
||||
</Grid>
|
||||
</materialDesign:DrawerHost>
|
||||
|
||||
</Window>
|
||||
51
ADP/Views/ShellView.xaml.cs
Normal file
51
ADP/Views/ShellView.xaml.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using UIShare.PubEvent;
|
||||
using Prism.Events;
|
||||
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.Shapes;
|
||||
|
||||
namespace ADP.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// ShellView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ShellView : Window
|
||||
{
|
||||
public ShellView(IEventAggregator eventAggregator)
|
||||
{
|
||||
InitializeComponent();
|
||||
//注册灰度遮罩层
|
||||
eventAggregator.GetEvent<OverlayEvent>().Subscribe(ShowOverlay);
|
||||
eventAggregator.GetEvent<WaitingEvent>().Subscribe(ShowWaitinglay);
|
||||
}
|
||||
|
||||
private void ShowWaitinglay(bool arg)
|
||||
{
|
||||
Waitinglay.Visibility = arg ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private void ShowOverlay(bool arg)
|
||||
{
|
||||
Overlay.Visibility = arg ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
|
||||
private void ColorZone_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
{
|
||||
Window.GetWindow(this)?.DragMove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user