diff --git a/FT472_20241126_051347.bak b/FT472_20241126_051347.bak new file mode 100644 index 0000000..6ee1bce Binary files /dev/null and b/FT472_20241126_051347.bak differ diff --git a/TestProject1/TestProject1.csproj b/TestProject1/TestProject1.csproj new file mode 100644 index 0000000..d87a666 --- /dev/null +++ b/TestProject1/TestProject1.csproj @@ -0,0 +1,19 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + + + + diff --git a/TestProject1/UnitTest1.cs b/TestProject1/UnitTest1.cs new file mode 100644 index 0000000..58d2373 --- /dev/null +++ b/TestProject1/UnitTest1.cs @@ -0,0 +1,31 @@ +using HslCommunication.Profinet.Siemens; + +namespace TestProject1 +{ + [TestClass] + public class UnitTest1 + { + [TestMethod] + public void TestMethod1() + { + SiemensS7Net plc_Conv = new SiemensS7Net(SiemensPLCS.S1500, "127.0.0.1"); + plc_Conv.ConnectTimeOut = 3; + OperateResult res = plc_Conv.ConnectServer(); + + if (res.IsSuccess) + { + Console.WriteLine(1); + } + else + { + Console.WriteLine(2); + } + + Console.ReadKey(); + } + + } + + + +} \ No newline at end of file diff --git a/TestProject1/Usings.cs b/TestProject1/Usings.cs new file mode 100644 index 0000000..b60884e --- /dev/null +++ b/TestProject1/Usings.cs @@ -0,0 +1,2 @@ +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using HslCommunication; \ No newline at end of file diff --git a/WPFWCSDemo.sln b/WPFWCSDemo.sln new file mode 100644 index 0000000..a5d6f78 --- /dev/null +++ b/WPFWCSDemo.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34003.232 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WPFWCSDemo", "WPFWCSDemo\WPFWCSDemo.csproj", "{604005A1-35A4-48E2-8011-20C38F2AC571}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject1", "TestProject1\TestProject1.csproj", "{BD8D724A-5381-4BBD-BB94-240AD27DD2A7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {604005A1-35A4-48E2-8011-20C38F2AC571}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {604005A1-35A4-48E2-8011-20C38F2AC571}.Debug|Any CPU.Build.0 = Debug|Any CPU + {604005A1-35A4-48E2-8011-20C38F2AC571}.Release|Any CPU.ActiveCfg = Release|Any CPU + {604005A1-35A4-48E2-8011-20C38F2AC571}.Release|Any CPU.Build.0 = Release|Any CPU + {BD8D724A-5381-4BBD-BB94-240AD27DD2A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD8D724A-5381-4BBD-BB94-240AD27DD2A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD8D724A-5381-4BBD-BB94-240AD27DD2A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD8D724A-5381-4BBD-BB94-240AD27DD2A7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {395F0C62-C9BD-4A94-801B-049F19941808} + EndGlobalSection +EndGlobal diff --git a/WPFWCSDemo/API/Task/StockIn/StockIn_Receive.cs b/WPFWCSDemo/API/Task/StockIn/StockIn_Receive.cs new file mode 100644 index 0000000..45151e7 --- /dev/null +++ b/WPFWCSDemo/API/Task/StockIn/StockIn_Receive.cs @@ -0,0 +1,54 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task.StockIn +{ + /// + /// 接收WMS推送的*入库*任务 + /// + public class StockIn_Receive + { + /// + /// 流水号 + /// + public string JobId { get; set; } + /// + /// 任务号 + /// + public string TaskId { get; set; } + /// + /// 托盘编号 + /// + public string PalletId { get; set; } + /// + /// 任务类型 1-入库 2-出库 3-移库 + /// + public int TaskType { get; set; } + /// + /// 源站点 + /// + public string SourceLocation { get; set; } + /// + /// 目标站点 + /// + public string TargetLocation { get; set; } + /// + /// 优先级 1→3 高→低 + /// + public int Priority { get; set; } + /// + /// 任务状态 + /// + [JsonIgnore] + public string TaskCode { get; set; } + /// + /// 调度状态 + /// + [JsonIgnore] + public string ScheduleCode { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/StockIn/StockIn_ReceiveResponse.cs b/WPFWCSDemo/API/Task/StockIn/StockIn_ReceiveResponse.cs new file mode 100644 index 0000000..229accc --- /dev/null +++ b/WPFWCSDemo/API/Task/StockIn/StockIn_ReceiveResponse.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task.StockIn +{ + /// + /// 【接收*入库*推送后】向wms反馈消息 + /// + public class StockIn_ReceiveResponse + { + /// + /// 作业号 + /// + public string JobId { get; set; } + /// + /// 反馈信息 + /// + public string Message { get; set; } + /// + /// 返回结果 0-正常 1-异常 + /// + public int Result { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/StockIn/StockIn_Request.cs b/WPFWCSDemo/API/Task/StockIn/StockIn_Request.cs new file mode 100644 index 0000000..a90311e --- /dev/null +++ b/WPFWCSDemo/API/Task/StockIn/StockIn_Request.cs @@ -0,0 +1,42 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task.StockIn +{ + /// + /// wcs主动向wms请求*入库*任务 + /// + public class StockIn_Request + { + /// + /// 接口名称 + /// + [JsonIgnore] + public string Name { get; set; } + /// + /// 任务号 + /// + public string TaskId { get; set; } + /// + /// 托盘号 + /// + public string PalletId { get; set; } + /// + /// 任务类型 + /// + public string TaskType { get; set; } + /// + /// 源站点 + /// + public string SourceLocation { get; set; } + /// + /// 发送结果 + /// + [JsonIgnore] + public string Result { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/StockIn/StockIn_RequestResponse.cs b/WPFWCSDemo/API/Task/StockIn/StockIn_RequestResponse.cs new file mode 100644 index 0000000..a005f54 --- /dev/null +++ b/WPFWCSDemo/API/Task/StockIn/StockIn_RequestResponse.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task.StockIn +{ + /// + /// 【向wms请求*入库*后】wms的返回消息 + /// + public class StockIn_RequestResponse + { + /// + /// 作业号 + /// + public string JobId { get; set; } + /// + /// 反馈信息 + /// + public string Message { get; set; } + /// + /// 返回结果 0-正常 1-异常 + /// + public int Result { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/StockOut/StockOut_Receive.cs b/WPFWCSDemo/API/Task/StockOut/StockOut_Receive.cs new file mode 100644 index 0000000..dec6ee6 --- /dev/null +++ b/WPFWCSDemo/API/Task/StockOut/StockOut_Receive.cs @@ -0,0 +1,54 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task.StockOut +{ + /// + /// 接收WMS推送的*出库*任务 + /// + public class StockOut_Receive + { + /// + /// 流水号 + /// + public string JobId { get; set; } + /// + /// 任务号 + /// + public string TaskId { get; set; } + /// + /// 托盘编号 + /// + public string PalletId { get; set; } + /// + /// 任务类型 1-入库 2-出库 3-移库 + /// + public int TaskType { get; set; } + /// + /// 源站点 + /// + public string SourceLocation { get; set; } + /// + /// 目标站点 + /// + public string TargetLocation { get; set; } + /// + /// 优先级 1→3 高→低 + /// + public int Priority { get; set; } + /// + /// 任务状态 + /// + [JsonIgnore] + public string TaskCode { get; set; } + /// + /// 调度状态 + /// + [JsonIgnore] + public string ScheduleCode { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/StockOut/StockOut_ReceiveReponse.cs b/WPFWCSDemo/API/Task/StockOut/StockOut_ReceiveReponse.cs new file mode 100644 index 0000000..6e92caf --- /dev/null +++ b/WPFWCSDemo/API/Task/StockOut/StockOut_ReceiveReponse.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task.StockOut +{ + /// + /// 【接收*出库*推送后】向wms反馈消息 + /// + public class StockOut_ReceiveReponse + { + /// + /// 作业号 + /// + public string JobId { get; set; } + /// + /// 反馈信息,可空 + /// + public string Message { get; set; } + /// + /// 返回结果 0-正常 1-异常 + /// + public int Result { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/Task_Receive.cs b/WPFWCSDemo/API/Task/Task_Receive.cs new file mode 100644 index 0000000..373ed30 --- /dev/null +++ b/WPFWCSDemo/API/Task/Task_Receive.cs @@ -0,0 +1,55 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task +{ + /// + /// 接收wms推送任务 + /// + public class Task_Receive + { + /// + /// 流水号 + /// + public string? JobId { get; set; } + /// + /// 任务号 + /// + [JsonIgnore] + public string? TaskId { get; set; } + /// + /// 托盘编号 + /// + public string? PalletId { get; set; } + /// + /// 任务类型 1-入库 2-出库 3-移库 + /// + public ushort TaskType { get; set; } + /// + /// 源站点 + /// + public string? SourceLocation { get; set; } + /// + /// 目标站点 + /// + public string? TargetLocation { get; set; } + /// + /// 优先级 1→3 高→低 + /// + public int Priority { get; set; } + /// + /// 任务状态 + /// + [JsonIgnore] + public string TaskState { get; set; } + /// + /// 调度状态 + /// + [JsonIgnore] + public string ScheduleState { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/Task_Response.cs b/WPFWCSDemo/API/Task/Task_Response.cs new file mode 100644 index 0000000..a616ced --- /dev/null +++ b/WPFWCSDemo/API/Task/Task_Response.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task +{ + /// + /// 【接收wms推送任务后】向wms反馈消息 + /// + public class Task_Response + { + /// + /// 作业号 + /// + public string? JobId { get; set; } + /// + /// 反馈信息,可空 + /// + public string? Message { get; set; } + /// + /// 返回结果 0-成功 1-失败 + /// + public int Result { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/Task_StateRequest.cs b/WPFWCSDemo/API/Task/Task_StateRequest.cs new file mode 100644 index 0000000..2b9962f --- /dev/null +++ b/WPFWCSDemo/API/Task/Task_StateRequest.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task +{ + /// + /// 根据任务状态请求wms-向wms反馈执行结果 + /// + public class Task_StateRequest + { + /// + /// 作业号 + /// + public string JobId { get; set; } + /// + /// 反馈信息 + /// + public string Message { get; set; } + + /// + /// 状态码 111-放货有货 121-取货无货 102-任务正常完成 103-任务人工完成 104-人工取消任务 + /// + public string Code { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/Task_StateRequestResponse.cs b/WPFWCSDemo/API/Task/Task_StateRequestResponse.cs new file mode 100644 index 0000000..d611b0c --- /dev/null +++ b/WPFWCSDemo/API/Task/Task_StateRequestResponse.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task +{ + /// + /// 向wms反馈任务状态(执行结果)后(完成、重分等)返回的消息 + /// + public class Task_StateRequestResponse + { + /// + /// 作业号 + /// + public string? JobId { get; set; } + /// + /// 【入库放货有货】重新分配的目标仓位 + /// + public string? TargetLocation { get; set; } + /// + /// 反馈信息 + /// + public string? Message { get; set; } + /// + /// 返回码 0-正常 1-异常 + /// + public int Result { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/Task_StockInRequest.cs b/WPFWCSDemo/API/Task/Task_StockInRequest.cs new file mode 100644 index 0000000..89fa77e --- /dev/null +++ b/WPFWCSDemo/API/Task/Task_StockInRequest.cs @@ -0,0 +1,42 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task +{ + /// + /// wcs向wms请求入库 + /// + public class Task_StockInRequest + { + /// + /// 接口名称 + /// + [JsonIgnore] + public string Name { get; set; } + /// + /// 任务号 + /// + public string TaskId { get; set; } + /// + /// 托盘号 + /// + public string PalletId { get; set; } + /// + /// 任务类型 + /// + public int TaskType { get; set; } + /// + /// 源站点 + /// + public string SourceLocation { get; set; } + /// + /// 发送结果 0-成功 1-失败 + /// + [JsonIgnore] + public int Result { get; set; } + } +} diff --git a/WPFWCSDemo/API/Task/Task_StockInRequestResponse.cs b/WPFWCSDemo/API/Task/Task_StockInRequestResponse.cs new file mode 100644 index 0000000..7563ca5 --- /dev/null +++ b/WPFWCSDemo/API/Task/Task_StockInRequestResponse.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.API.Task +{ + /// + /// 【wcs向wms请求入库后】wms的返回消息 + /// + public class Task_StockInRequestResponse + { + /// + /// 流水号 + /// + public string? JobId { get; set; } + /// + /// 目标站 + /// + public string? TargetLocation { get; set; } + /// + /// 反馈信息 + /// + public string? Message { get; set; } + /// + /// 反馈结果 + /// + public int Result { get; set; } + } +} diff --git a/WPFWCSDemo/App.config b/WPFWCSDemo/App.config new file mode 100644 index 0000000..afaa34e --- /dev/null +++ b/WPFWCSDemo/App.config @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WPFWCSDemo/App.xaml b/WPFWCSDemo/App.xaml new file mode 100644 index 0000000..8446a6d --- /dev/null +++ b/WPFWCSDemo/App.xaml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WPFWCSDemo/App.xaml.cs b/WPFWCSDemo/App.xaml.cs new file mode 100644 index 0000000..710be3d --- /dev/null +++ b/WPFWCSDemo/App.xaml.cs @@ -0,0 +1,193 @@ +using Quartz; +using Quartz.Impl; +using Quartz.Simpl; +using Serilog; +using Serilog.Events; +using System; +using System.Configuration; +using System.Data; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using WPFWCSDemo.Schedules.CircleRGV; +using WPFWCSDemo.Schedules.CommonTask; +using WPFWCSDemo.Schedules.TaskFinish; +using WPFWCSDemo.Utilities; +using WPFWCSDemo.ViewModels; + +namespace WPFWCSDemo +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + private IScheduler _scheduler; + public App() + { + InitializeComponent(); + + //Serilog其他 + //Serilog日志配置 + //Debug- + //Info-调度信息 + //Warning-设备读写/连接异常 + //Error-执行异常,交互异常 + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + //.Filter.ByIncludingOnly(logEvent => logEvent.Level == LogEventLevel.Debug) + .WriteTo.File(path: $"D:/Logs/Debug/Debug.txt", outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}", restrictedToMinimumLevel: LogEventLevel.Debug, rollingInterval: RollingInterval.Day) + .WriteTo.File(path: $"D:/Logs/Info/Info.txt", outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}", restrictedToMinimumLevel: LogEventLevel.Information, rollingInterval: RollingInterval.Day) + .WriteTo.File(path: $"D:/Logs/Warning/Warning.txt", outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}", restrictedToMinimumLevel: LogEventLevel.Warning, rollingInterval: RollingInterval.Day) + .WriteTo.File(path: $"D:/Logs/Error/Error.txt", outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}", restrictedToMinimumLevel: LogEventLevel.Error, rollingInterval: RollingInterval.Day) + //.Filter.ByExcluding(logEvent => logEvent.Level == LogEventLevel.Warning) + .Enrich.FromLogContext() + .CreateLogger(); + + //获取app.config中sql连接字符串 + SqlHelper.ConStr = ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString; + + + //检查进程是否已经启动,已经启动则显示报错信息退出程序。 + string strProcessName = System.Diagnostics.Process.GetCurrentProcess().ProcessName; + if (System.Diagnostics.Process.GetProcessesByName(strProcessName).Length > 1) + { + MessageBox.Show("对不起,本地已经有系统正在运行", "退出", MessageBoxButton.OK, MessageBoxImage.Exclamation); + Current.Shutdown(); + return; + } + + } + + + + protected async override void OnStartup(StartupEventArgs e) + { + try + { + Log.Information("**********************************Application Is Started**********************************"); + Log.Information("**********************************Application Is Started**********************************"); + Log.Information("**********************************Application Is Started**********************************"); + + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + + //============================================================================================== + + Log.Information("【Application is Starting】环穿设备初始化中..."); + CircleRGVsViewModel.InitializeRgv(); + //CircleRGVsViewModel.RGVStationInitialize(); + Log.Information("【Application is Starting】环穿设备初始化完成!"); + + //============================================================================================== + + Log.Information("【Application is Starting】报警信息初始化中..."); + AlarmViewModel.AlarmInitialize(); + Log.Information("【Application is Starting】报警信息初始化完成!"); + + //============================================================================================== + + Log.Information("【Application is Starting】调度程序初始化中..."); + + ISchedulerFactory schedulerFactory = new StdSchedulerFactory(); + _scheduler = schedulerFactory.GetScheduler().Result; + await _scheduler.Start(); + + Log.Information("【Application is Starting】调度程序启动中..."); + + #region 注册环穿调度任务 + + Log.Information("【Application is Starting】设备调度初始化中..."); + GetScheduleJob(typeof(CircleRGVSchedule), "circleRGVJob", "circleRGVTrigger", "circleRGVSchedule", 2000); + #endregion + + //------------------------------------------------------------------------------- + + #region 调度任务处理 + + //任务处理---注册任务 + Log.Information("【Application is Starting】任务处理调度初始化中..."); + GetScheduleJob(typeof(TaskFinishSchedule), "taskHandlerJob", "taskHandlerTrigger", "taskHandlerSchedule", 1000); + #endregion + + //------------------------------------------------------------------------------- + + #region 全局任务 + + //全局任务---注册任务 + Log.Information("【Application is Starting】全局任务初始化中..."); + GetScheduleJob(typeof(CommonTask), "globalTaskJob", "globalTTrigger", "commonTask", 1000); + #endregion + + + Log.Information("【Application is Starting】调度程序初始化完成!"); + + //============================================================================================== + + stopwatch.Stop(); + Log.Information($"【Application is Starting】WCS工程已启动,用时{stopwatch.Elapsed.TotalSeconds}s"); + + SqlHelper.NewEventLog("WCS调度已启动", "SYS"); + } + catch (Exception ex) + { + Log.Error($"【Application is Starting】{ex.Message}"); + Log.Error($"【Application is Starting】{ex.InnerException}"); + Current.Shutdown(); + } + + + } + + + + protected override void OnExit(ExitEventArgs e) + { + base.OnExit(e); + Log.Information("【Application is Exiting】程序正在退出!"); + _scheduler.Shutdown(true).Wait(); + //Current.Shutdown(); + } + + + /// + /// Quartz调度任务注册 + /// + /// 类名 + /// 作业名称 + /// 触发器名称 + /// 任务组名称 + private async void GetScheduleJob(Type className, string jobName, string triggerName, string group,int time) + { + var method = typeof(JobBuilder) + .GetMethods() + .First(m => m.Name == "Create" && m.IsGenericMethod); + + var genericMethod = method.MakeGenericMethod(className); + var jobBuilder = genericMethod.Invoke(null, null); + + //任务处理---注册任务 + IJobDetail job = ((JobBuilder)jobBuilder) + //.Create() + .WithIdentity(jobName, group) + .DisallowConcurrentExecution() + .Build(); + + //任务处理---触发器 + ITrigger trigger = TriggerBuilder + .Create() + .WithIdentity(triggerName, group) + .StartNow() + .WithSimpleSchedule(x => x + .WithInterval(TimeSpan.FromMilliseconds(time)) + .RepeatForever()) + .Build(); + + await _scheduler.ScheduleJob(job, trigger); + } + + + + } +} diff --git a/WPFWCSDemo/AssemblyInfo.cs b/WPFWCSDemo/AssemblyInfo.cs new file mode 100644 index 0000000..8b5504e --- /dev/null +++ b/WPFWCSDemo/AssemblyInfo.cs @@ -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) +)] diff --git a/WPFWCSDemo/Common/ConnectionUrl.cs b/WPFWCSDemo/Common/ConnectionUrl.cs new file mode 100644 index 0000000..57ec7d4 --- /dev/null +++ b/WPFWCSDemo/Common/ConnectionUrl.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.Common +{ + public class ConnectionUrl + { + /// + /// wms连接url + /// + public static string wms = $"{ConfigurationManager.AppSettings["WmsIP"]}:{ConfigurationManager.AppSettings["WmsPort"]}"; + /// + /// 输送机IP + /// + public static string Conv = $"{ConfigurationManager.AppSettings["Conv"]}"; + /// + /// 1#提升机IP + /// + public static string lift1 = $"{ConfigurationManager.AppSettings["Lift1"]}"; + /// + /// 2#提升机IP + /// + public static string lift2 = $"{ConfigurationManager.AppSettings["Lift2"]}"; + /// + /// 1#穿梭车IP + /// + public static string rGV1 = $"{ConfigurationManager.AppSettings["RGV1"]}"; + /// + /// 2#穿梭车IP + /// + public static string rGV2 = $"{ConfigurationManager.AppSettings["RGV2"]}"; + /// + /// 1#堆垛机IP + /// + public static string stacker1 = $"{ConfigurationManager.AppSettings["Stacker1"]}"; + /// + /// 2#堆垛机IP + /// + public static string stacker2 = $"{ConfigurationManager.AppSettings["Stacker2"]}"; + /// + /// 3#堆垛机IP + /// + public static string stacker3 = $"{ConfigurationManager.AppSettings["Stacker3"]}"; + } +} diff --git a/WPFWCSDemo/Common/Converters/ColorToBrushConverter.cs b/WPFWCSDemo/Common/Converters/ColorToBrushConverter.cs new file mode 100644 index 0000000..5bb26fe --- /dev/null +++ b/WPFWCSDemo/Common/Converters/ColorToBrushConverter.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; + +namespace WPFWCSDemo.Common.Converters +{ + [ValueConversion(typeof(Color), typeof(Brush))] + public class ColorToBrushConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is Color color) + { + return new SolidColorBrush(color); + } + return Binding.DoNothing; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is SolidColorBrush brush) + { + return brush.Color; + } + return default(Color); + } + } +} diff --git a/WPFWCSDemo/Common/CustomAttributes/TimerTaskAttribute.cs b/WPFWCSDemo/Common/CustomAttributes/TimerTaskAttribute.cs new file mode 100644 index 0000000..14d069d --- /dev/null +++ b/WPFWCSDemo/Common/CustomAttributes/TimerTaskAttribute.cs @@ -0,0 +1,67 @@ +using Quartz; +using Quartz.Impl; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.Common.CustomAttributes +{ + [AttributeUsage(AttributeTargets.Method)] + public class TimerTaskAttribute:Attribute + { + public int Second { get; set; } + public int Minute { get; set; } + public int Hour { get; set; } + + private IScheduler _scheduler; + + /// + /// Quartz调度任务注册 + /// + /// 类名 + /// 作业名称 + /// 触发器名称 + /// 任务组名称 + private async void GetScheduleJob(Type className, string jobName, string triggerName, string group, int time) + { + ISchedulerFactory schedulerFactory = new StdSchedulerFactory(); + _scheduler = schedulerFactory.GetScheduler().Result; + await _scheduler.Start(); + + var method = typeof(JobBuilder) + .GetMethods() + .First(m => m.Name == "Create" && m.IsGenericMethod); + + var genericMethod = method.MakeGenericMethod(className); + var jobBuilder = genericMethod.Invoke(null, null); + + //任务处理---注册任务 + IJobDetail job = ((JobBuilder)jobBuilder) + //.Create() + .WithIdentity(jobName, group) + .DisallowConcurrentExecution() + .Build(); + + //任务处理---触发器 + ITrigger trigger = TriggerBuilder + .Create() + .WithIdentity(triggerName, group) + .StartNow() + .WithSimpleSchedule(x => x + .WithInterval(TimeSpan.FromMilliseconds(time)) + .RepeatForever()) + .Build(); + + await _scheduler.ScheduleJob(job, trigger); + } + + + + + + } + + +} diff --git a/WPFWCSDemo/Common/RGVStation.cs b/WPFWCSDemo/Common/RGVStation.cs new file mode 100644 index 0000000..fc553ed --- /dev/null +++ b/WPFWCSDemo/Common/RGVStation.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WPFWCSDemo.Common +{ + /// + /// RGV取放货站点 + /// + public class RGVStation + { + /// + /// 环穿运行设备数量 + /// + public const int RGVCount = 13; + + /// + /// H线供实垛 1001 + /// + public const int LineH_Goods_In = 1001; + /// + /// M线供实垛 1003 + /// + public const int LineM_Goods_In = 1003; + /// + /// L线供实垛 1005 + /// + public const int LineL_Goods_In = 1005; + /// + /// G1线供实垛 1007 + /// + public const int LineG1_Goods_In = 1007; + /// + /// G2线供实垛 1008 + /// + public const int LineG2_Goods_In = 1008; + + + /// + /// 立库口送实垛1-1009 + /// + public const int LineToWarehouse1_Out = 1009; + /// + /// 立库口送实垛2-1010 + /// + public const int LineToWarehouse2_Out = 1010; + /// + /// G线送实垛-1011 + /// + public const int LineG_Goods_Out = 1011; + /// + /// H线送实垛-1012 + /// + public const int LineH_Goods_Out = 1012; + + //============================================================================================== + + /// + /// 供空托 1013 + /// + public const int LineGH_Pallets_In = 1013; + + /// + /// 放空托1 1002 + /// + public const int LineH_Pallets_Out = 1002; + /// + /// 放空托2 1004 + /// + public const int LineG_Pallets_Out = 1004; + /// + /// 放空托3 1006 + /// + public const int LineLM_Pallets_Out = 1006; + + } +} diff --git a/WPFWCSDemo/Data/AppDbContext.cs b/WPFWCSDemo/Data/AppDbContext.cs new file mode 100644 index 0000000..8dd21a3 --- /dev/null +++ b/WPFWCSDemo/Data/AppDbContext.cs @@ -0,0 +1,141 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Xml; +using WPFWCSDemo.Models.Tables; +using WPFWCSDemo.Utilities; + +namespace WPFWCSDemo.Data +{ + public class AppDbContext : DbContext + { + public DbSet Tasks { get; set; } + public DbSet TaskViews { get; set; } + public DbSet TaskHistoriesView { get; set; } + public DbSet TaskHistories { get; set; } + public DbSet Alarms { get; set; } + public DbSet AlarmHistories { get; set; } + public DbSet LoadedState { get; set; } + public DbSet Event_Log { get; set; } + public DbSet LineState { get; set; } + public DbSet ConvRequest { get; set; } + + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlServer(ConfigurationManager.ConnectionStrings["ConStr"].ConnectionString); + } + + + /// + /// 配置库与库表的映射关系 + /// + /// + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + //TASK表配置 + modelBuilder.Entity(e => + { + e.ToTable("TASK"); + e.HasKey(t => t.TaskId); + }); + + //TASK_VIEW表配置 + modelBuilder.Entity(e => + { + e.ToView("TASK_VIEW"); + e.Property(t => t.JobId).HasColumnName("环穿编号"); + e.Property(t => t.TaskId).HasColumnName("任务号"); + e.Ignore(t => t.PalletId); + e.Property(t => t.TaskType).HasColumnName("任务类型"); + e.Property(t => t.TaskState).HasColumnName("任务状态"); + e.Property(t => t.ScheduleState).HasColumnName("调度状态"); + e.Property(t => t.SourceLocation).HasColumnName("源站点"); + e.Property(t => t.TargetLocation).HasColumnName("目标站点"); + e.Ignore(t => t.ReportState); + e.Ignore(t => t.Priority); + e.Property(t => t.CreateTime).HasColumnName("生成时间"); + e.Property(t => t.ScheduleTime).HasColumnName("调度时间"); + e.HasNoKey(); + }); + + //TASK_HISTORY表配置 + modelBuilder.Entity(e => + { + e.ToTable("TASK_HISTORY"); + e.HasKey(t => t.Id); + }); + + //TASK_HISTORY_VIEW表配置 + modelBuilder.Entity(e => + { + e.ToView("TASK_HISTORY_VIEW"); + e.Property(t => t.JobId).HasColumnName("环穿编号"); + e.Property(t => t.TaskId).HasColumnName("任务号"); + e.Ignore(t => t.PalletId); + e.Property(t => t.TaskType).HasColumnName("任务类型"); + e.Property(t => t.TaskState).HasColumnName("任务状态"); + e.Property(t => t.ScheduleState).HasColumnName("调度状态"); + e.Property(t => t.SourceLocation).HasColumnName("源站点"); + e.Property(t => t.TargetLocation).HasColumnName("目标站点"); + e.Ignore(t => t.ReportState); + e.Ignore(t => t.Priority); + e.Property(t => t.CreateTime).HasColumnName("生成时间"); + e.Property(t => t.ScheduleTime).HasColumnName("调度时间"); + e.Property(t => t.FinishTime).HasColumnName("结束时间"); + e.HasNoKey(); + }); + + //ALARM表配置 + modelBuilder.Entity(e => + { + e.ToTable("ALARM"); + e.HasKey(a => a.Point_Id); + }); + + //ALARM_LOG表配置 + modelBuilder.Entity(e => + { + e.ToTable("ALARM_LOG"); + e.HasKey(a => a.Id); + }); + + //LOADEDSTATE表配置 + modelBuilder.Entity(e => + { + //e.ToTable("LoadedState"); + e.HasKey(a => a.Station); + }); + + //EVENT_LOG表配置 + modelBuilder.Entity(e => + { + e.ToTable("EVENT_LOG"); + e.HasKey(a => a.Id); + }); + + //LINESTATE表配置 + modelBuilder.Entity(e => + { + e.ToTable("LINESTATE"); + e.HasKey(a => a.Name); + }); + + //CONVREQUEST表配置 + modelBuilder.Entity(e => + { + e.ToTable("CONVREQUEST"); + e.HasKey(a => a.Id); + }); + + } + } +} diff --git a/WPFWCSDemo/MainWindow.xaml b/WPFWCSDemo/MainWindow.xaml new file mode 100644 index 0000000..6bd669e --- /dev/null +++ b/WPFWCSDemo/MainWindow.xaml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WPFWCSDemo/Views/DevicesNavigationView.xaml.cs b/WPFWCSDemo/Views/DevicesNavigationView.xaml.cs new file mode 100644 index 0000000..cafccd2 --- /dev/null +++ b/WPFWCSDemo/Views/DevicesNavigationView.xaml.cs @@ -0,0 +1,40 @@ +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 WPFWCSDemo.Views +{ + /// + /// DevicesNavigationView.xaml 的交互逻辑 + /// + public partial class DevicesNavigationView : Page + { + private static Frame _navagationFrame; + public DevicesNavigationView() + { + InitializeComponent(); + DataContext = new ViewModels.DevicesNavigationViewModel(_navagationFrame); + } + + /// + /// 获取主页导航的Frame对象 + /// + /// + public static void GetMainFrame(Frame frame) + { + _navagationFrame = frame; + } + + } +} diff --git a/WPFWCSDemo/Views/DevicesView.xaml b/WPFWCSDemo/Views/DevicesView.xaml new file mode 100644 index 0000000..039e9da --- /dev/null +++ b/WPFWCSDemo/Views/DevicesView.xaml @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WPFWCSDemo/Views/DevicesView.xaml.cs b/WPFWCSDemo/Views/DevicesView.xaml.cs new file mode 100644 index 0000000..b8cd70f --- /dev/null +++ b/WPFWCSDemo/Views/DevicesView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace WPFWCSDemo.Views +{ + /// + /// DevicesView.xaml 的交互逻辑 + /// + public partial class DevicesView : Page + { + public DevicesView() + { + InitializeComponent(); + } + } +} diff --git a/WPFWCSDemo/Views/HelperView.xaml b/WPFWCSDemo/Views/HelperView.xaml new file mode 100644 index 0000000..6b40cd2 --- /dev/null +++ b/WPFWCSDemo/Views/HelperView.xaml @@ -0,0 +1,14 @@ + + + + + + diff --git a/WPFWCSDemo/Views/HelperView.xaml.cs b/WPFWCSDemo/Views/HelperView.xaml.cs new file mode 100644 index 0000000..0c36430 --- /dev/null +++ b/WPFWCSDemo/Views/HelperView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace WPFWCSDemo.Views +{ + /// + /// HelperView.xaml 的交互逻辑 + /// + public partial class HelperView : Page + { + public HelperView() + { + InitializeComponent(); + } + } +} diff --git a/WPFWCSDemo/Views/LineManagementView.xaml b/WPFWCSDemo/Views/LineManagementView.xaml new file mode 100644 index 0000000..3c529d3 --- /dev/null +++ b/WPFWCSDemo/Views/LineManagementView.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/WPFWCSDemo/Views/LineManagementView.xaml.cs b/WPFWCSDemo/Views/LineManagementView.xaml.cs new file mode 100644 index 0000000..6029d79 --- /dev/null +++ b/WPFWCSDemo/Views/LineManagementView.xaml.cs @@ -0,0 +1,29 @@ +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; +using WPFWCSDemo.ViewModels; + +namespace WPFWCSDemo.Views +{ + /// + /// LineManagementView.xaml 的交互逻辑 + /// + public partial class LineManagementView : Page + { + public LineManagementView() + { + InitializeComponent(); + } + } +} diff --git a/WPFWCSDemo/Views/LogView.xaml b/WPFWCSDemo/Views/LogView.xaml new file mode 100644 index 0000000..d1cb7ac --- /dev/null +++ b/WPFWCSDemo/Views/LogView.xaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + diff --git a/WPFWCSDemo/Views/LogView.xaml.cs b/WPFWCSDemo/Views/LogView.xaml.cs new file mode 100644 index 0000000..92f276e --- /dev/null +++ b/WPFWCSDemo/Views/LogView.xaml.cs @@ -0,0 +1,30 @@ +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; +using WPFWCSDemo.ViewModels; + +namespace WPFWCSDemo.Views +{ + /// + /// LogView.xaml 的交互逻辑 + /// + public partial class LogView : Page + { + public LogView() + { + InitializeComponent(); + DataContext = new LogViewModel(); + } + } +} diff --git a/WPFWCSDemo/Views/MonitorView.xaml b/WPFWCSDemo/Views/MonitorView.xaml new file mode 100644 index 0000000..3af4cc3 --- /dev/null +++ b/WPFWCSDemo/Views/MonitorView.xaml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WPFWCSDemo/Views/MonitorView.xaml.cs b/WPFWCSDemo/Views/MonitorView.xaml.cs new file mode 100644 index 0000000..649032d --- /dev/null +++ b/WPFWCSDemo/Views/MonitorView.xaml.cs @@ -0,0 +1,33 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +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; +using WPFWCSDemo.ViewModels; + +namespace WPFWCSDemo.Views +{ + /// + /// MonitorView.xaml 的交互逻辑 + /// + public partial class MonitorView : Page + { + public MonitorView() + { + InitializeComponent(); + DataContext = new MonitorViewModel(); + } + } + +} diff --git a/WPFWCSDemo/Views/Settings/AboutView.xaml b/WPFWCSDemo/Views/Settings/AboutView.xaml new file mode 100644 index 0000000..f0474d4 --- /dev/null +++ b/WPFWCSDemo/Views/Settings/AboutView.xaml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http://www.yctd.cn/ + + + + + + + + + + + diff --git a/WPFWCSDemo/Views/Settings/AboutView.xaml.cs b/WPFWCSDemo/Views/Settings/AboutView.xaml.cs new file mode 100644 index 0000000..775d3ec --- /dev/null +++ b/WPFWCSDemo/Views/Settings/AboutView.xaml.cs @@ -0,0 +1,29 @@ +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 WPFWCSDemo.Views.Settings +{ + /// + /// AboutView.xaml 的交互逻辑 + /// + public partial class AboutView : Page + { + public AboutView() + { + InitializeComponent(); + DataContext = new ViewModels.Settings.AboutViewModel(); + } + } +} diff --git a/WPFWCSDemo/Views/Settings/SettingView.xaml b/WPFWCSDemo/Views/Settings/SettingView.xaml new file mode 100644 index 0000000..8976af9 --- /dev/null +++ b/WPFWCSDemo/Views/Settings/SettingView.xaml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WPFWCSDemo/Views/Settings/SettingView.xaml.cs b/WPFWCSDemo/Views/Settings/SettingView.xaml.cs new file mode 100644 index 0000000..b03f74d --- /dev/null +++ b/WPFWCSDemo/Views/Settings/SettingView.xaml.cs @@ -0,0 +1,29 @@ +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 WPFWCSDemo.Views +{ + /// + /// SettingView.xaml 的交互逻辑 + /// + public partial class SettingView : Page + { + public SettingView() + { + InitializeComponent(); + DataContext = new ViewModels.SettingViewModel(settingFrame); + } + } +} diff --git a/WPFWCSDemo/Views/Settings/SkinView.xaml b/WPFWCSDemo/Views/Settings/SkinView.xaml new file mode 100644 index 0000000..529c4ee --- /dev/null +++ b/WPFWCSDemo/Views/Settings/SkinView.xaml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WPFWCSDemo/Views/Settings/SkinView.xaml.cs b/WPFWCSDemo/Views/Settings/SkinView.xaml.cs new file mode 100644 index 0000000..4e0cf60 --- /dev/null +++ b/WPFWCSDemo/Views/Settings/SkinView.xaml.cs @@ -0,0 +1,29 @@ +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 WPFWCSDemo.Views.Settings +{ + /// + /// SkinView.xaml 的交互逻辑 + /// + public partial class SkinView : Page + { + public SkinView() + { + InitializeComponent(); + DataContext = new ViewModels.Settings.SkinViewModel(); + } + } +} diff --git a/WPFWCSDemo/Views/Settings/SystemView.xaml b/WPFWCSDemo/Views/Settings/SystemView.xaml new file mode 100644 index 0000000..ad0cd78 --- /dev/null +++ b/WPFWCSDemo/Views/Settings/SystemView.xaml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +