移植程序,完成commandtree的MVVM模式

This commit is contained in:
hsc 2025-11-04 14:31:06 +08:00
parent c3438c6a99
commit a585333636
50 changed files with 3264 additions and 43 deletions

View File

@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.14.36221.1 VisualStudioVersion = 17.14.36221.1
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BaseFrame", "BaseFrame\BaseFrame.csproj", "{FC10E4D4-0AA3-487B-B023-F8D2949E45ED}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BOB", "BOB\BOB.csproj", "{FC10E4D4-0AA3-487B-B023-F8D2949E45ED}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model", "Model\Model.csproj", "{6D9764D9-B4DA-43E2-A9D7-40A6C871A6B3}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model", "Model\Model.csproj", "{6D9764D9-B4DA-43E2-A9D7-40A6C871A6B3}"
EndProject EndProject
@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Service", "Service\Service.
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{6C684FE1-C773-4B9D-89F1-9266C7B32DC0}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{6C684FE1-C773-4B9D-89F1-9266C7B32DC0}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Command", "Command\Command.csproj", "{49D249DE-CB09-4390-89DC-6165965C3933}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -45,6 +47,10 @@ Global
{6C684FE1-C773-4B9D-89F1-9266C7B32DC0}.Debug|Any CPU.Build.0 = Debug|Any CPU {6C684FE1-C773-4B9D-89F1-9266C7B32DC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C684FE1-C773-4B9D-89F1-9266C7B32DC0}.Release|Any CPU.ActiveCfg = Release|Any CPU {6C684FE1-C773-4B9D-89F1-9266C7B32DC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6C684FE1-C773-4B9D-89F1-9266C7B32DC0}.Release|Any CPU.Build.0 = Release|Any CPU {6C684FE1-C773-4B9D-89F1-9266C7B32DC0}.Release|Any CPU.Build.0 = Release|Any CPU
{49D249DE-CB09-4390-89DC-6165965C3933}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{49D249DE-CB09-4390-89DC-6165965C3933}.Debug|Any CPU.Build.0 = Debug|Any CPU
{49D249DE-CB09-4390-89DC-6165965C3933}.Release|Any CPU.ActiveCfg = Release|Any CPU
{49D249DE-CB09-4390-89DC-6165965C3933}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -1,7 +1,7 @@
<prism:PrismApplication x:Class="BaseFrame.App" <prism:PrismApplication x:Class="BOB.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BaseFrame" xmlns:local="clr-namespace:BOB"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:prism="http://prismlibrary.com/"> xmlns:prism="http://prismlibrary.com/">
<Application.Resources> <Application.Resources>

View File

@ -1,7 +1,7 @@
using BaseFrame.ViewModels; using BOB.ViewModels;
using BaseFrame.ViewModels.Dialogs; using BOB.ViewModels.Dialogs;
using BaseFrame.Views; using BOB.Views;
using BaseFrame.Views.Dialogs; using BOB.Views.Dialogs;
using Castle.DynamicProxy; using Castle.DynamicProxy;
using System.Configuration; using System.Configuration;
using System.Data; using System.Data;
@ -9,7 +9,7 @@ using System.Reflection;
using System.Windows; using System.Windows;
using static System.Runtime.InteropServices.JavaScript.JSType; using static System.Runtime.InteropServices.JavaScript.JSType;
namespace BaseFrame namespace BOB
{ {
/// <summary> /// <summary>
/// Interaction logic for App.xaml /// Interaction logic for App.xaml

View File

@ -42,6 +42,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Command\Command.csproj" />
<ProjectReference Include="..\Common\Common.csproj" /> <ProjectReference Include="..\Common\Common.csproj" />
<ProjectReference Include="..\Logger\Logger.csproj" /> <ProjectReference Include="..\Logger\Logger.csproj" />
<ProjectReference Include="..\Model\Model.csproj" /> <ProjectReference Include="..\Model\Model.csproj" />

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BOB.Models
{
public class InstructionNode
{
public string Name { get; set; }
public ObservableCollection<InstructionNode> Children { get; set; } = new();
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BOB.Models
{
public class SubProgramItem
{
public string Name { get; set; } = "";
public string FilePath { get; set; } = "";
}
}

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

96
BOB/SystemConfig.cs Normal file
View File

@ -0,0 +1,96 @@
using Logger;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Reflection;
namespace BOB
{
public class SystemConfig
{
private static readonly object _lock = new();
private static SystemConfig? _instance;
public static SystemConfig Instance
{
get
{
lock (_lock)
{
if (_instance == null)
{
_instance = new();
_instance.LoadFromFile();
}
return _instance;
}
}
}
[JsonIgnore]
public string SystemPath { get; set; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "BOB系统");
public int PerformanceLevel { get; set; } = 50;
public string DLLFilePath { get; set; } = @"D:\BOB\指令\";
public string SubProgramFilePath { get; set; } = @"D:\BOB\子程序\";
public string DefaultSubProgramFilePath { get; set; } = "";
// 配置加载方法
public void LoadFromFile()
{
string configPath = Path.Combine(SystemPath, "system.config");
if (!File.Exists(configPath))
{
string json = JsonConvert.SerializeObject(Instance, Formatting.Indented);
File.WriteAllText(configPath, json);
return;
}
try
{
string json = File.ReadAllText(configPath);
var loadedConfig = JsonConvert.DeserializeObject<SystemConfig>(json);
// 复制所有可写属性排除JsonIgnore属性
PropertyInfo[] properties = typeof(SystemConfig).GetProperties();
foreach (var prop in properties)
{
if (prop.CanWrite && !Attribute.IsDefined(prop, typeof(JsonIgnoreAttribute)))
{
prop.SetValue(this, prop.GetValue(loadedConfig));
}
}
}
catch (Exception ex)
{
LoggerHelper.Logger.Error($"配置加载失败: {ex.Message}");
}
}
public void SaveToFile()
{
lock (_lock)
{
try
{
if (!Directory.Exists(SystemPath))
Directory.CreateDirectory(SystemPath);
string configPath = Path.Combine(SystemPath, "system.config");
string json = JsonConvert.SerializeObject(this, Formatting.Indented);
File.WriteAllText(configPath, json);
LoggerHelper.Logger.Info("系统配置已保存。");
}
catch (Exception ex)
{
LoggerHelper.Logger.Error($"配置保存失败: {ex.Message}");
}
}
}
}
}

View File

@ -0,0 +1,333 @@
using BOB.Models;
using Common.Attributes;
using Logger;
using Microsoft.IdentityModel.Logging;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Xml;
namespace BOB.ViewModels
{
public class CommandTreeViewModel:BindableBase
{
#region
private string _SearchText;
public string SearchText
{
get => _SearchText;
set => SetProperty(ref _SearchText, value);
}
public ObservableCollection<InstructionNode> _InstructionTree=new();
public ObservableCollection<InstructionNode> InstructionTree
{
get => _InstructionTree;
set => SetProperty(ref _InstructionTree, value);
}
public ObservableCollection<Assembly> Assemblies { get; set; } = [];
public ObservableCollection<SubProgramItem> SubPrograms { get; set; } = [];
private Dictionary<object, InstructionNode> _treeViewItemMap = [];
private TreeViewItem _subProgramRootNode;
private readonly Dictionary<string, XmlDocument> _xmlDocumentCache = [];
#endregion
public ICommand LoadedCommand { get; set; }
public ICommand SearchEnterCommand { get; set; }
public ICommand TreeDoubleClickCommand { get; set; }
public ICommand ReloadCommand { get; set; }
public CommandTreeViewModel()
{
LoadedCommand = new DelegateCommand(Loaded);
SearchEnterCommand = new DelegateCommand(Search);
TreeDoubleClickCommand = new DelegateCommand(TreeDoubleClick);
ReloadCommand = new DelegateCommand(Reload);
}
#region
private void Reload()
{
LoadAllAssemblies();
LoadSubPrograms();
LoadInstructionsToTreeView();
}
private void TreeDoubleClick()
{
}
private void Search()
{
}
private void Loaded()
{
Directory.CreateDirectory(SystemConfig.Instance.DLLFilePath);
Directory.CreateDirectory(SystemConfig.Instance.SubProgramFilePath);
LoadAllAssemblies();
LoadSubPrograms();
LoadInstructionsToTreeView();
}
#endregion
#region
/// <summary>
/// 加载指定目录下的所有DLL
/// </summary>
private void LoadAllAssemblies()
{
Assemblies.Clear();
foreach (var dllPath in Directory.GetFiles(SystemConfig.Instance.DLLFilePath, "*.dll"))
{
try
{
var assembly = Assembly.LoadFrom(dllPath);
Assemblies.Add(assembly);
// 加载对应的XML注释文件
string xmlPath = Path.ChangeExtension(dllPath, ".xml");
if (File.Exists(xmlPath))
{
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlPath);
_xmlDocumentCache[assembly.FullName!] = xmlDoc;
}
catch (Exception xmlEx)
{
LoggerHelper.Logger.Warn($"加载XML注释失败: {Path.GetFileName(xmlPath)} - {xmlEx.Message}");
}
}
}
catch (Exception ex)
{
LoggerHelper.Logger.Warn($"无法加载程序集 {Path.GetFileName(dllPath)}: {ex.Message}");
}
}
}
// 子程序加载方法
private void LoadSubPrograms()
{
SubPrograms.Clear();
if (!Directory.Exists(SystemConfig.Instance.SubProgramFilePath))
{
Directory.CreateDirectory(SystemConfig.Instance.SubProgramFilePath);
return;
}
foreach (var filePath in Directory.GetFiles(SystemConfig.Instance.SubProgramFilePath, "*.ats"))
{
try
{
SubPrograms.Add(new SubProgramItem
{
Name = Path.GetFileNameWithoutExtension(filePath),
FilePath = filePath
});
}
catch (Exception ex)
{
LoggerHelper.Logger.Warn($"加载子程序错误: {filePath} - {ex.Message}");
}
}
}
/// <summary>
/// 加载指令集到TreeView
/// </summary>
private void LoadInstructionsToTreeView()
{
InstructionTree.Clear();
var controlRootNode = new InstructionNode
{
Name = "系统指令",
};
InstructionTree.Add(controlRootNode);
// 循环开始
controlRootNode.Children.Add(new InstructionNode
{
Name = "循环开始",
});
// 循环结束
controlRootNode.Children.Add(new InstructionNode
{
Name = "循环结束",
});
// ----------------------
// 子程序 根节点
// ----------------------
var subProgramRoot = new InstructionNode
{
Name = "子程序",
};
InstructionTree.Add(subProgramRoot);
foreach (var subProgram in SubPrograms)
{
subProgramRoot.Children.Add(new InstructionNode
{
Name = subProgram.Name,
});
}
// ----------------------
// 动态 DLL 指令
// ----------------------
foreach (var assembly in Assemblies)
{
List<Type> validTypes = new List<Type>();
try
{
var types = assembly.GetTypes().Where(t =>
t.IsPublic &&
!t.IsNested &&
(t.IsClass || t.IsValueType) &&
(!t.IsAbstract || t.IsSealed) &&
t.GetCustomAttribute<ATSCommandAttribute>() != null);
foreach (var type in types)
{
if (type.GetCustomAttribute<BrowsableAttribute>()?.Browsable == false)
continue;
var allMethods = new HashSet<MethodInfo>();
GetPublicMethods(type, allMethods);
if (allMethods.Count > 0)
validTypes.Add(type);
}
}
catch (Exception ex)
{
LoggerHelper.Logger.Error($"加载类型错误: {assembly.FullName} - {ex.Message}");
}
if (validTypes.Count > 0)
{
var assemblyNode = new InstructionNode
{
Name = assembly.GetName().Name,
};
InstructionTree.Add(assemblyNode);
_treeViewItemMap[assembly] = assemblyNode;
foreach (var type in validTypes)
{
var typeNode = new InstructionNode
{
Name = type.Name,
};
assemblyNode.Children.Add(typeNode);
_treeViewItemMap[type] = typeNode;
var allMethods = new HashSet<MethodInfo>();
GetPublicMethods(type, allMethods);
foreach (var method in allMethods)
{
if (method.IsSpecialName) continue;
if (method.DeclaringType == typeof(object)) continue;
string[] ignoreMethods = { "GetType", "ToString", "Equals", "GetHashCode" };
if (ignoreMethods.Contains(method.Name)) continue;
if (method.GetCustomAttribute<BrowsableAttribute>()?.Browsable == false) continue;
if (type.IsAbstract && type.IsSealed && !method.IsStatic) continue;
var parameters = method.GetParameters();
var paramText = string.Join(", ", parameters.Select(p => $"{p.ParameterType.Name} {p.Name}"));
var methodNode = new InstructionNode
{
Name = $"{method.Name}({paramText})",
};
typeNode.Children.Add(methodNode);
_treeViewItemMap[method] = methodNode;
}
}
}
}
}
#endregion
/// <summary>
/// 递归获取类型的所有公共方法(包括继承的方法),但跳过被重写的方法
/// </summary>
/// <param name="type">要处理的目标类型</param>
/// <param name="methods">存储方法的集合</param>
private void GetPublicMethods(Type type, HashSet<MethodInfo> methods)
{
// 获取当前类型的所有公共方法(包括继承的)
var allMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
.Where(m => !m.IsSpecialName &&
m.DeclaringType != typeof(object))
.ToList();
// 按方法签名分组
var groupedMethods = allMethods
.GroupBy(m => new { m.Name, Parameters = string.Join(",", m.GetParameters().Select(p => p.ParameterType.FullName)) });
foreach (var group in groupedMethods)
{
// 从组中选择声明类型最接近当前类型(即继承层次最深)的方法
MethodInfo? selectedMethod = null;
int minDepth = int.MaxValue;
foreach (var method in group)
{
// 计算声明类型的深度
int depth = 0;
Type? current = type;
Type declaringType = method.DeclaringType!;
while (current != null && current != declaringType)
{
depth++;
current = current.BaseType;
}
// 如果找到声明类型且在继承链上
if (current == declaringType)
{
if (selectedMethod == null || depth < minDepth)
{
selectedMethod = method;
minDepth = depth;
}
}
}
if (selectedMethod != null)
{
methods.Add(selectedMethod);
}
}
}
}
}

View File

@ -4,7 +4,7 @@ using Prism.Commands;
using Prism.Mvvm; using Prism.Mvvm;
using System.Windows.Input; using System.Windows.Input;
namespace BaseFrame.ViewModels.Dialogs namespace BOB.ViewModels.Dialogs
{ {
public class MessageBoxViewModel : BindableBase, IDialogAware public class MessageBoxViewModel : BindableBase, IDialogAware
{ {

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BOB.ViewModels
{
public class LogAreaViewModel
{
public LogAreaViewModel()
{
}
}
}

View File

@ -11,7 +11,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
namespace BaseFrame.ViewModels namespace BOB.ViewModels
{ {
public class MainViewModel : BindableBase,INavigationAware,IDialogAware public class MainViewModel : BindableBase,INavigationAware,IDialogAware
{ {

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BOB.ViewModels
{
public class ParametersManagerViewModel
{
public ParametersManagerViewModel()
{
}
}
}

View File

@ -1,4 +1,4 @@
using BaseFrame.Views; using BOB.Views;
using Common.PubEvents; using Common.PubEvents;
using MaterialDesignThemes.Wpf; using MaterialDesignThemes.Wpf;
using System; using System;
@ -9,7 +9,7 @@ using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
namespace BaseFrame.ViewModels namespace BOB.ViewModels
{ {
public class ShellViewModel : BindableBase public class ShellViewModel : BindableBase
{ {

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BOB.ViewModels
{
public class SingleStepEditViewModel
{
public SingleStepEditViewModel()
{
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BOB.ViewModels
{
public class StepsManagerViewModel
{
public StepsManagerViewModel()
{
}
}
}

View File

@ -0,0 +1,74 @@
<UserControl x:Class="BOB.Views.CommandTree"
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:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:BOB.Views"
xmlns:model="clr-namespace:BOB.Models"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<prism:InvokeCommandAction Command="{Binding LoadedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<GroupBox Header="指令">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- 搜索框 -->
<StackPanel Grid.Row="0"
Orientation="Horizontal"
Margin="10,0,7,12"
VerticalAlignment="Center">
<TextBox MinWidth="150"
Height="25"
Margin="0,0,5,0"
VerticalContentAlignment="Center"
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyDown">
<prism:InvokeCommandAction Command="{Binding SearchEnterCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</StackPanel>
<!-- TreeView -->
<TreeView Grid.Row="1"
ItemsSource="{Binding InstructionTree}" >
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type model:InstructionNode}"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
<!-- 双击 -->
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<prism:InvokeCommandAction Command="{Binding TreeDoubleClickCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<!-- 右键菜单 -->
<TreeView.ContextMenu>
<ContextMenu>
<MenuItem Header="重新加载"
Command="{Binding ReloadCommand}" />
</ContextMenu>
</TreeView.ContextMenu>
</TreeView>
</Grid>
</GroupBox>
</Grid>
</UserControl>

View File

@ -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 BOB.Views
{
/// <summary>
/// CommandTreeView.xaml 的交互逻辑
/// </summary>
public partial class CommandTree : UserControl
{
public CommandTree()
{
InitializeComponent();
}
}
}

View File

@ -1,9 +1,9 @@
<UserControl x:Class="BaseFrame.Views.Dialogs.MessageBoxView" <UserControl x:Class="BOB.Views.Dialogs.MessageBoxView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BaseFrame.Views.Dialogs" xmlns:local="clr-namespace:BOB.Views.Dialogs"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
mc:Ignorable="d" mc:Ignorable="d"
xmlns:prism="http://prismlibrary.com/" xmlns:prism="http://prismlibrary.com/"

View File

@ -13,7 +13,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
namespace BaseFrame.Views.Dialogs namespace BOB.Views.Dialogs
{ {
/// <summary> /// <summary>
/// MessageBoxView.xaml 的交互逻辑 /// MessageBoxView.xaml 的交互逻辑

29
BOB/Views/LogArea.xaml Normal file
View File

@ -0,0 +1,29 @@
<UserControl x:Class="BOB.Views.LogArea"
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:prism="http://prismlibrary.com/"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800">
<Grid>
<GroupBox Header="系统运行日志">
<ListView FontWeight="DemiBold"
ItemsSource="{Binding LogEntries}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectedItem="{Binding SelectedLog, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Foreground="{Binding Color}"
Text="{Binding Message}"
TextWrapping="Wrap" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</GroupBox>
</Grid>
</UserControl>

28
BOB/Views/LogArea.xaml.cs Normal file
View File

@ -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 BOB.Views
{
/// <summary>
/// LogArea.xaml 的交互逻辑
/// </summary>
public partial class LogArea : UserControl
{
public LogArea()
{
InitializeComponent();
}
}
}

43
BOB/Views/MainView.xaml Normal file
View File

@ -0,0 +1,43 @@
<UserControl x:Class="BOB.Views.MainView"
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:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vs="clr-namespace:BOB.Views"
mc:Ignorable="d"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="1080"
d:DesignWidth="1920">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1.5*"/>
<RowDefinition />
</Grid.RowDefinitions>
<vs:CommandTree Grid.Row="0" Margin="5"
Grid.Column="0"
Grid.RowSpan="2" />
<vs:StepsManager Grid.Row="0"
Margin="5"
Grid.Column="1"
Grid.ColumnSpan="2"/>
<vs:SingleStepEdit Grid.Row="0"
Margin="5"
Grid.Column="3" />
<vs:LogArea Grid.Row="1"
Margin="5"
Grid.Column="1"
Grid.ColumnSpan="2" />
<vs:ParametersManager Grid.Row="1"
Margin="5"
Grid.Column="3" />
</Grid>
</UserControl>

View File

@ -13,7 +13,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
namespace BaseFrame.Views namespace BOB.Views
{ {
/// <summary> /// <summary>
/// MainView.xaml 的交互逻辑 /// MainView.xaml 的交互逻辑

View File

@ -0,0 +1,135 @@
<UserControl x:Class="BOB.Views.ParametersManager"
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:prism="http://prismlibrary.com/"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">
<UserControl.Resources>
<CollectionViewSource x:Key="VisibleParameters"
Source="{Binding Program.Parameters}"
IsLiveFilteringRequested="True">
<CollectionViewSource.LiveFilteringProperties>
<sys:String>IsVisible</sys:String>
</CollectionViewSource.LiveFilteringProperties>
</CollectionViewSource>
</UserControl.Resources>
<Grid>
<GroupBox Header="设备/参数">
<TabControl>
<!-- 参数Tab -->
<TabItem Header="参数">
<DataGrid Padding="10"
Background="Transparent"
ItemsSource="{Binding Source={StaticResource VisibleParameters}}"
AutoGenerateColumns="False"
CanUserAddRows="False"
SelectionMode="Extended"
SelectionUnit="FullRow"
SelectedItem="{Binding SelectedParameter, Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTextColumn Header="类别"
IsReadOnly="True" />
<DataGridTextColumn Header="参数名"
Binding="{Binding Name}"
IsReadOnly="True" />
<DataGridTextColumn Header="类型"
Binding="{Binding Type}"
IsReadOnly="True" />
<DataGridTextColumn Header="值"
MinWidth="20"
IsReadOnly="True" />
</DataGrid.Columns>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="新增"
Command="{Binding ParameterAddCommand}" />
<MenuItem Header="编辑"
Command="{Binding ParameterEditCommand}"
IsEnabled="{Binding SelectedParameter}" />
<MenuItem Header="删除"
Foreground="Red"
Command="{Binding ParameterDeleteCommand}"
IsEnabled="{Binding SelectedParameter}" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
</TabItem>
<!-- 设备Tab -->
<TabItem Header="设备">
<DataGrid Padding="10"
Background="Transparent"
ItemsSource="{Binding Program.Devices}"
AutoGenerateColumns="False"
CanUserAddRows="False"
IsReadOnly="True"
SelectionMode="Extended"
SelectedItem="{Binding SelectedDevice, Mode=TwoWay}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="设备状态">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Ellipse Width="16"
Height="16"
StrokeThickness="1"
Stroke="DarkGray">
<Ellipse.Style>
<Style TargetType="Ellipse">
<Setter Property="Fill"
Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding Connected}"
Value="True">
<Setter Property="Fill"
Value="LimeGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Connected}"
Value="False">
<Setter Property="Fill"
Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="设备名称"
Binding="{Binding Name}" />
<DataGridTextColumn Header="备注"
Binding="{Binding Description}" />
</DataGrid.Columns>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="新增"
Command="{Binding DeviceAddCommand}" />
<MenuItem Header="编辑"
Command="{Binding DeviceEditCommand}"
IsEnabled="{Binding SelectedDevice}" />
<MenuItem Header="删除"
Foreground="Red"
Command="{Binding DeviceDeleteCommand}"
IsEnabled="{Binding SelectedDevice}" />
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
</TabItem>
</TabControl>
</GroupBox>
</Grid>
</UserControl>

View File

@ -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 BOB.Views
{
/// <summary>
/// ParametersManager.xaml 的交互逻辑
/// </summary>
public partial class ParametersManager : UserControl
{
public ParametersManager()
{
InitializeComponent();
}
}
}

View File

@ -1,9 +1,9 @@
<UserControl x:Class="BaseFrame.Views.ProgressView" <UserControl x:Class="BOB.Views.ProgressView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BaseFrame.Views" xmlns:local="clr-namespace:BOB.Views"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800"> d:DesignWidth="800">

View File

@ -12,7 +12,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Shapes; using System.Windows.Shapes;
namespace BaseFrame.Views namespace BOB.Views
{ {
/// <summary> /// <summary>
/// ProgressView.xaml 的交互逻辑 /// ProgressView.xaml 的交互逻辑

View File

@ -1,4 +1,4 @@
<Window x:Class="BaseFrame.Views.ShellView" <Window x:Class="BOB.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@ -14,9 +14,11 @@
Title="ShellView" Title="ShellView"
d:DesignHeight="1080" d:DesignHeight="1080"
d:DesignWidth="1920"> d:DesignWidth="1920">
<WindowChrome.WindowChrome>
<WindowChrome GlassFrameThickness="-1" />
</WindowChrome.WindowChrome>
<materialDesign:DrawerHost x:Name="MainDrawerHost"
<materialDesign:DrawerHost x:Name="MainDrawerHost"
IsLeftDrawerOpen="{Binding IsLeftDrawerOpen, Mode=TwoWay}"> IsLeftDrawerOpen="{Binding IsLeftDrawerOpen, Mode=TwoWay}">
<!-- ✅ 左侧抽屉内容 --> <!-- ✅ 左侧抽屉内容 -->
@ -51,7 +53,9 @@
<RowDefinition /> <RowDefinition />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- 顶部工具栏 --> <!-- 顶部工具栏 -->
<materialDesign:ColorZone Mode="PrimaryMid"> <materialDesign:ColorZone Mode="PrimaryMid"
Background="DodgerBlue"
MouseLeftButtonDown="ColorZone_MouseLeftButtonDown">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" /> <ColumnDefinition Width="auto" />

View File

@ -1,5 +1,6 @@
using Common.PubEvent; using Common.PubEvent;
using Common.PubEvents; using Common.PubEvents;
using MahApps.Metro.Controls;
using Prism.Events; using Prism.Events;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -15,12 +16,12 @@ using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Shapes; using System.Windows.Shapes;
namespace BaseFrame.Views namespace BOB.Views
{ {
/// <summary> /// <summary>
/// ShellView.xaml 的交互逻辑 /// ShellView.xaml 的交互逻辑
/// </summary> /// </summary>
public partial class ShellView : Window public partial class ShellView
{ {
public ShellView(IEventAggregator eventAggregator) public ShellView(IEventAggregator eventAggregator)
{ {
@ -43,5 +44,13 @@ namespace BaseFrame.Views
if (DialogHost.IsOpen) if (DialogHost.IsOpen)
DialogHost.DialogContent = new ProgressView(); DialogHost.DialogContent = new ProgressView();
} }
private void ColorZone_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Window.GetWindow(this)?.DragMove();
}
}
} }
} }

View File

@ -0,0 +1,135 @@
<UserControl x:Class="BOB.Views.SingleStepEdit"
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:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:BOB.Views"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<GroupBox Header="单步编辑">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<!-- 名称 -->
<StackPanel Grid.Row="0"
Orientation="Horizontal"
Margin="7">
<Label Width="60"
Content="名称" />
<TextBox MinWidth="120"
Text="{Binding SelectedStep.Name}" />
</StackPanel>
<!-- 合格条件 -->
<StackPanel Grid.Row="1"
Orientation="Horizontal"
Margin="7">
<Label Width="60"
Content="合格条件" />
<TextBox MinWidth="120"
Text="{Binding SelectedStep.OKExpression}" />
</StackPanel>
<!-- 跳转 -->
<StackPanel Grid.Row="2"
Orientation="Horizontal"
Margin="7">
<Label Width="60"
Content="跳转"
ToolTip="格式OK跳转序号/NG跳转序号默认为0/0)" />
<TextBox MinWidth="120" />
</StackPanel>
<!-- 备注 -->
<StackPanel Grid.Row="3"
Orientation="Horizontal"
Margin="7">
<Label Width="60"
Content="备注" />
<TextBox MinWidth="120"
Text="{Binding SelectedStep.Description}" />
</StackPanel>
<!-- 参数编辑区 -->
<Grid Grid.Row="4">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal"
Margin="7,0">
<Label Content="参数" />
</StackPanel>
<ScrollViewer Grid.Row="1"
Margin="40,0,0,0"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<StackPanel>
<!-- 主参数 -->
<ItemsControl ItemsSource="{Binding SelectedStep.Method.Parameters}">
<ItemsControl.ItemTemplate>
<DataTemplate>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- 子程序参数 -->
<ItemsControl ItemsSource="{Binding SelectedStep.SubProgram.Parameters}">
<ItemsControl.ItemTemplate>
<DataTemplate>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</Grid>
<!-- 按钮 -->
<StackPanel Grid.Row="5"
Orientation="Horizontal"
FlowDirection="RightToLeft"
Margin="5,0">
<Button Width="90"
Content="取消"
Command="{Binding CancelEditCommand}" />
<Button Width="90"
Margin="20,0"
Content="保存"
Command="{Binding SaveStepCommand}" />
</StackPanel>
</Grid>
</GroupBox>
</Grid>
</UserControl>

View File

@ -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 BOB.Views
{
/// <summary>
/// SingleStepEdit.xaml 的交互逻辑
/// </summary>
public partial class SingleStepEdit : UserControl
{
public SingleStepEdit()
{
InitializeComponent();
}
}
}

123
BOB/Views/StepsManager.xaml Normal file
View File

@ -0,0 +1,123 @@
<UserControl x:Class="BOB.Views.StepsManager"
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:dd="urn:gong-wpf-dragdrop"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:BOB.Views"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<GroupBox Header="{Binding Title}">
<DataGrid x:Name="ProgramDataGrid"
AutoGenerateColumns="False"
Background="Transparent"
CanUserAddRows="False"
CanUserSortColumns="False"
ItemsSource="{Binding Program.StepCollection}"
SelectedItem="{Binding SelectedStep, Mode=TwoWay}"
SelectionMode="Extended"
SelectionUnit="FullRow">
<!-- 行样式 -->
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="Black" />
<Style.Triggers>
<DataTrigger Binding="{Binding Result}"
Value="0">
<Setter Property="Background"
Value="DodgerBlue" />
<Setter Property="Foreground"
Value="White" />
</DataTrigger>
<DataTrigger Binding="{Binding Result}"
Value="1">
<Setter Property="Background"
Value="LimeGreen" />
<Setter Property="Foreground"
Value="White" />
</DataTrigger>
<DataTrigger Binding="{Binding Result}"
Value="2">
<Setter Property="Background"
Value="Red" />
<Setter Property="Foreground"
Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<!-- 列 -->
<DataGrid.Columns>
<DataGridCheckBoxColumn Width="58"
Binding="{Binding IsUsed, UpdateSourceTrigger=PropertyChanged}"
Header="启用" />
<DataGridTextColumn Binding="{Binding Index}"
Header="序号"
IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Name}"
Header="名称"
IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding StepType}"
Header="类型"
IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Method.FullName}"
Header="指令类型"
IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Method.Name}"
Header="指令"
IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding OKExpression}"
Header="合格条件"
IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding RunTime}"
Header="耗时(ms)"
IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Result}"
Header="结果"
IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Description}"
Header="备注" />
</DataGrid.Columns>
<!-- ContextMenu MVVM化 -->
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="编辑"
Command="{Binding DataContext.EditStepCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" />
<MenuItem Header="复制"
Command="{Binding DataContext.CopyStepCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" />
<MenuItem Header="粘贴"
Command="{Binding DataContext.PasteStepCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" />
<MenuItem Header="删除"
Foreground="Red"
Command="{Binding DataContext.DeleteStepCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</ContextMenu>
</DataGrid.ContextMenu>
<!-- 键盘 删除键绑定 Delete 命令 -->
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewKeyDown">
<i:InvokeCommandAction Command="{Binding DeleteStepCommand}"
CommandParameter="{Binding SelectedStep}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
</GroupBox>
</Grid>
</UserControl>

View File

@ -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 BOB.Views
{
/// <summary>
/// StepsManager.xaml 的交互逻辑
/// </summary>
public partial class StepsManager : UserControl
{
public StepsManager()
{
InitializeComponent();
}
}
}

View File

@ -1,15 +0,0 @@
<UserControl x:Class="BaseFrame.Views.MainView"
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:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="1080"
d:DesignWidth="1920">
<Grid>
<Button Command="{Binding testcommand}" Width="150" Height='150'/>
</Grid>
</UserControl>

14
Command/Command.csproj Normal file
View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,268 @@
using Common.Attributes;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Command
{
[ATSCommand]
public static class CommandApplication
{
/// <summary>
/// 打开外部应用程序
/// </summary>
/// <param name="route">程序路径</param>
/// <param name="waitShutdown">是否等待关闭</param>
/// <param name="AdminRun">是否请求管理员运行</param>
public static void OpenApplication(string route, bool waitShutdown, bool AdminRun)
{
// 创建一个新的进程实例
Process process = new Process();
try
{
// 指定要启动的程序路径
process.StartInfo.FileName = route;
// 指定是否等待程序关闭
process.StartInfo.UseShellExecute = !waitShutdown;
if (AdminRun) process.StartInfo.Verb = "runas";
// 启动程序
process.Start();
// 如果需要等待程序关闭,则等待程序退出
if (waitShutdown)
{
process.WaitForExit();
}
}
catch (Exception ex)
{
Console.WriteLine("错误!: " + ex.Message);
}
finally
{
// 确保进程对象被释放
process.Dispose();
}
}
/// <summary>
/// 使用默认方式打开一个文件
/// </summary>
/// <param name="route">文件路径</param>
public static void OpenFile(string route)
{
// 创建一个新的进程实例
Process process = new Process();
try
{
// 指定要启动的程序路径
process.StartInfo.FileName = route;
process.StartInfo.UseShellExecute = true;
// 启动程序
process.Start();
}
catch (Exception ex)
{
Console.WriteLine("错误!: " + ex.Message);
}
finally
{
// 确保进程对象被释放
process.Dispose();
}
}
// Python引擎相关字段
private static Process _pythonProcess;
private static string _pythonPath = string.Empty;
private static bool _isPythonEngineInitialized = false;
/// <summary>
/// 初始化python引擎
/// </summary>
/// <param name="py路径">Python解释器路径</param>
public static void Initialization_Python(string py路径)
{
try
{
// 验证Python路径是否存在
if (string.IsNullOrEmpty(py路径) || !File.Exists(py路径))
{
throw new FileNotFoundException($"Python解释器路径不存在: {py路径}");
}
// 验证是否为Python可执行文件
var fileInfo = new FileInfo(py路径);
if (!fileInfo.Name.ToLower().Contains("python"))
{
Console.WriteLine("警告: 指定的文件可能不是Python解释器");
}
// 测试Python是否能正常运行
var testProcess = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = py路径,
Arguments = "--version",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
testProcess.Start();
testProcess.WaitForExit(5000); // 5秒超时
if (testProcess.ExitCode != 0)
{
throw new InvalidOperationException($"Python解释器验证失败退出码: {testProcess.ExitCode}");
}
_pythonPath = py路径;
_isPythonEngineInitialized = true;
Console.WriteLine($"Python引擎初始化成功版本: {testProcess.StandardOutput.ReadToEnd().Trim()}");
}
catch (Exception ex)
{
_isPythonEngineInitialized = false;
_pythonPath = string.Empty;
Console.WriteLine($"初始化Python引擎失败: {ex.Message}");
throw;
}
}
/// <summary>
/// 运行python脚本
/// </summary>
/// <param name="路径">Python脚本路径</param>
/// <returns>脚本执行结果</returns>
public static string Run_Python_Script(string )
{
if (!_isPythonEngineInitialized)
{
throw new InvalidOperationException("Python引擎未初始化请先调用初始化python引擎");
}
if (string.IsNullOrEmpty() || !File.Exists())
{
throw new FileNotFoundException($"Python脚本路径不存在: {路径}");
}
Process process = null;
try
{
process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = _pythonPath,
Arguments = $"\"{}\"",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
var output = new StringBuilder();
var error = new StringBuilder();
// 设置输出和错误处理
process.OutputDataReceived += (sender, e) =>
{
if (!string.IsNullOrEmpty(e.Data))
output.AppendLine(e.Data);
};
process.ErrorDataReceived += (sender, e) =>
{
if (!string.IsNullOrEmpty(e.Data))
error.AppendLine(e.Data);
};
process.Start();
// 异步读取输出
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
var outputResult = output.ToString().Trim();
var errorResult = error.ToString().Trim();
if (process.ExitCode != 0)
{
throw new InvalidOperationException($"Python脚本执行失败退出码: {process.ExitCode}, 错误: {errorResult}");
}
return string.IsNullOrEmpty(outputResult) ? "执行成功" : outputResult;
}
catch (Exception ex)
{
Console.WriteLine($"运行Python脚本失败: {ex.Message}");
throw;
}
finally
{
process?.Dispose();
}
}
/// <summary>
/// 释放python引擎
/// </summary>
/// <param name="py">Python解释器路径可选用于验证</param>
public static void Release_Python(string py = "")
{
try
{
if (!string.IsNullOrEmpty(py) && py != _pythonPath)
{
Console.WriteLine($"警告: 释放的Python路径与当前初始化路径不匹配");
}
// 如果有正在运行的Python进程尝试终止它
if (_pythonProcess != null && !_pythonProcess.HasExited)
{
try
{
_pythonProcess.Kill();
_pythonProcess.WaitForExit(1000);
}
catch (Exception ex)
{
Console.WriteLine($"终止Python进程时出错: {ex.Message}");
}
}
_pythonPath = string.Empty;
_isPythonEngineInitialized = false;
_pythonProcess = null;
Console.WriteLine("Python引擎已释放");
}
catch (Exception ex)
{
Console.WriteLine($"释放Python引擎失败: {ex.Message}");
throw;
}
}
}
}

261
Command/CommandArray.cs Normal file
View File

@ -0,0 +1,261 @@
using Common.Attributes;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Command
{
[ATSCommand]
public static class CommandArray
{
#region
/// <summary>
/// 从数组中获取指定位置的元素。
/// </summary>
/// <param name="Array">要索引的数组。</param>
/// <param name="Index">要获取的元素的位置。</param>
/// <returns>指定位置的元素。</returns>
public static object IndexArray(object Array, int Index)
{
return ((dynamic)Array)[Index];
}
/// <summary>
/// 设置数组中指定位置的元素为给定值。
/// </summary>
/// <param name="Array">要设置元素的数组。</param>
/// <param name="Location">要设置的元素的位置。</param>
/// <param name="Value">要设置的值。</param>
/// <returns>修改后的数组。</returns>
public static object SetArrayElement(object Array, int Location, object Value)
{
((dynamic)Array)[Location] = (dynamic)Value;
return Array;
}
/// <summary>
/// 将给定数组的长度设置为指定值,并返回一个新的数组。
/// 如果指定的长度小于原始数组的长度,则截取原始数组的一部分作为新数组。
/// </summary>
/// <param name="Arr">要设置长度的数组。</param>
/// <param name="Length">新数组的长度。</param>
/// <returns>新的数组,或者原始数组(如果输入参数不是数组类型)。</returns>
public static object SetArrayLength(object Arr, int Length)
{
if (Arr is Array)
{
// 创建一个新的数组实例来存储结果
Array temp = Array.CreateInstance(Arr.GetType()!.GetElementType()!, Length);
// 确定复制的长度,取原始数组长度和目标长度的最小值
int CopyLength = Math.Min(((Array)Arr).Length, Length);
// 复制原始数组的元素到新数组中
Array.Copy((Array)Arr, temp, CopyLength);
return temp;
}
else
{
// 如果输入参数不是数组类型,则返回原始数组
return Arr;
}
}
/// <summary>
/// 在指定位置插入元素到数组中。
/// </summary>
/// <param name="Arr">要插入元素的数组。</param>
/// <param name="Location">要插入元素的位置。</param>
/// <param name="InsertElement">要插入的元素。</param>
/// <returns>插入元素后的数组。</returns>
public static object SetArrayInsertElement(object Arr, int Location, object InsertElement)
{
// 将数组转换为可编辑列表
var temp = Enumerable.ToList((dynamic)Arr);
// 在指定位置插入元素
temp.Insert(Location, (dynamic)InsertElement);
// 如果原数组是数组类型,则将可编辑列表转换回数组并返回
if (Arr is Array)
{
return Enumerable.ToArray(temp);
}
// 返回插入元素后的可编辑列表
return temp;
}
/// <summary>
/// 从数组中删除指定的元素。
/// </summary>
/// <param name="Arr">要删除元素的数组。</param>
/// <param name="DeleteElement">要从数组中删除的元素。</param>
/// <returns>删除元素后的数组。</returns>
public static object SetArrayDeleteElement(object Arr, object DeleteElement)
{
// 将数组转换为可编辑列表
var temp = Enumerable.ToList((dynamic)Arr);
// 从列表中移除指定元素
temp.Remove((dynamic)DeleteElement);
// 如果原数组是数组类型,则将可编辑列表转换回数组并返回
if (Arr is Array)
{
return Enumerable.ToArray(temp);
}
// 返回删除元素后的可编辑列表
return temp;
}
/// <summary>
/// 从数组中删除指定位置的元素。
/// </summary>
/// <param name="Arr">要删除元素的数组。</param>
/// <param name="DeleteElementLocation">要从数组中删除的元素的位置。</param>
/// <returns>删除元素后的数组。</returns>
public static object SetArrayDeleteLocationElement(object Arr, int DeleteElementLocation)
{
var temp = Enumerable.ToList((dynamic)Arr);
temp.RemoveAt(DeleteElementLocation);
if (Arr is Array)
{
return Enumerable.ToArray(temp);
}
return temp;
}
/// <summary>
/// 在数组中寻找第一个匹配的元素,并返回其索引位置。
/// </summary>
/// <param name="Arr">要搜索的数组。</param>
/// <param name="QueryElement">要寻找的元素。</param>
/// <returns>要寻找的元素在数组中的第一个匹配项的索引;如果未找到匹配项,则为 -1。</returns>
public static int ArrayQueryFirstMatchElement(object Arr, object QueryElement)
{
if (Arr is Array)
{
return Array.IndexOf((dynamic)Arr, (dynamic)QueryElement);
}
return ((dynamic)Arr).IndexOf((dynamic)QueryElement);
}
/// <summary>
/// 替换数组中第一个匹配的元素为指定的新元素。
/// </summary>
/// <param name="Arr">要进行替换操作的数组。</param>
/// <param name="FirstMatchElement">要替换的元素。</param>
/// <param name="ReplaceElement">要替换为的新元素。</param>
/// <returns>替换后的数组。</returns>
public static object ArrayReplaceFirstMatchElement(object Arr, object FirstMatchElement, object ReplaceElement)
{
var temp = Enumerable.ToList((dynamic)Arr);
int Location = ArrayQueryFirstMatchElement(Arr, FirstMatchElement);
temp[Location] = (dynamic)ReplaceElement;
return temp;
}
/// <summary>
/// 将数组中所有匹配的元素替换为指定的新元素。
/// </summary>
/// <param name="Arr">要进行替换操作的数组。</param>
/// <param name="MatchElement">要替换的元素。</param>
/// <param name="ReplaceElement">要替换为的新元素。</param>
/// <returns>替换后的数组。</returns>
public static object ArrayReplaceAllMatchElement(object Arr, object MatchElement, object ReplaceElement)
{
var temp = Enumerable.ToList((dynamic)Arr);
int = temp.Count;
for (int i = 0; i < ; i++)
{
if (((dynamic)Arr)[i] == (dynamic)MatchElement)
{
((dynamic)Arr)[i] = (dynamic)ReplaceElement;
}
}
return Arr;
}
/// <summary>
/// 反转数组中元素的顺序。
/// </summary>
/// <param name="Arr">要反转的数组。</param>
/// <returns>反转后的数组。</returns>
public static object ArrayReverse(object Arr)
{
var temp = Enumerable.ToList((dynamic)Arr);
temp.Reverse();
if (Arr is Array)
{
return Enumerable.ToArray(temp);
}
return temp;
}
/// <summary>
/// 对数组进行排序。
/// </summary>
/// <param name="Arr">要排序的数组。</param>
/// <returns>排序后的数组。</returns>
public static object ArraySorting(object Arr)
{
var temp = Enumerable.ToList((dynamic)Arr);
temp = Enumerable.ToList(Enumerable.Order(temp));
if (Arr is Array)
{
return Enumerable.ToArray(temp);
}
return temp;
}
/// <summary>
/// 获取数组的长度。
/// </summary>
/// <param name="Arr">要获取长度的数组。</param>
/// <returns>数组的长度。</returns>
public static int GetArrayLength(object Arr)
{
if (Arr is Array)
{
return ((Array)Arr).Length;
}
return ((ICollection)Arr).Count;
}
/// <summary>
/// 将对象转换为数组。
/// </summary>
/// <param name="Arr">要转换的对象。</param>
/// <returns>转换后的数组。</returns>
public static object objectConvertToArray(object Arr)
{
return Enumerable.ToArray((dynamic)Arr);
}
/// <summary>
/// 将对象转换为列表。
/// </summary>
/// <param name="Arr">要转换的对象。</param>
/// <returns>转换后的列表。</returns>
public static object objectConvertToList(object Arr)
{
return Enumerable.ToList((dynamic)Arr);
}
/// <summary>
/// 从数组中截取指定长度的子数组。
/// </summary>
/// <param name="Arr">要截取的数组。</param>
/// <param name="StartLocation">截取开始的位置。</param>
/// <param name="Length">要截取的长度。</param>
/// <returns>截取得到的子数组。</returns>
public static object ArrayCapture(object Arr, int StartLocation, int Length)
{
var temp = Enumerable.ToList((dynamic)Arr);
temp = Enumerable.ToList(Enumerable.Take(Enumerable.Skip(temp, StartLocation), Length));
if (Arr is Array)
{
return Enumerable.ToArray(temp);
}
return temp;
}
#endregion
}
}

473
Command/CommandMath.cs Normal file
View File

@ -0,0 +1,473 @@
using Common.Attributes;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Command
{
public enum ComparisonFuncEnum
{
Big,
BigOrEqual,
Small,
SmallOrEqual,
Equal,
NotEqual
}
[ATSCommand]
public static class CommandMath
{
#region Double类型数据
/// <summary>
/// 两数相加(Param1 + Param2)
/// </summary>
/// <param name="Param1">传入值实数1</param>
/// <param name="Param2">传入值实数2</param>
/// <example>Param1:9 Param2:2 返回值:11</example>
/// <returns></returns>
public static double ParamAdd(double Param1, double Param2)
{
return Param1 + Param2;
}
/// <summary>
/// 两数相减(Param1 - Param2)
/// </summary>
/// <param name="Param1">传入值实数1</param>
/// <param name="Param2">传入值实数2</param>
/// <example>Param1:9 Param2:2 返回值:7</example>
/// <returns></returns>
public static double ParamReduce(double Param1, double Param2)
{
return Param1 - Param2;
}
/// <summary>
/// 两数相乘(Param1 * Param2)
/// </summary>
/// <param name="Param1">传入值实数1</param>
/// <param name="Param2">传入值实数2</param>
/// <example>Param1:9 Param2:2 返回值:18</example>
/// <returns></returns>
public static double ParamMult(double Param1, double Param2)
{
return Param1 * Param2;
}
/// <summary>
/// 两数相除(Param1 / Param2)
/// </summary>
/// <param name="Param1">传入值实数1</param>
/// <param name="Param2">传入值实数2</param>
/// <param name="Param3">传入值:保留几位小数</param>
/// <example>Param1:10 Param2:3 Param3:3 返回值3.333</example>
/// <example>Param1:11 Param2:3 Param3:2 返回值3.67</example>
/// <returns></returns>
public static double ParamDivide(double Param1, double Param2, int Param3)
{
return Math.Round((Param1 / Param2), Param3);
}
/// <summary>
/// 两数相除求余(Param1 % Param2)
/// </summary>
/// <param name="Param1">传入值实数1</param>
/// <param name="Param2">传入值实数2</param>
/// <example>Param1:9 Param2:2 返回值:1</example>
/// <returns></returns>
public static double ParamRemainder(double Param1, double Param2)
{
return Param1 % Param2;
}
/// <summary>
/// 实数开根号
/// </summary>
/// <param name="Param1">传入值实数1</param>
/// <example>Param1:16 返回值4</example>
/// <returns></returns>
public static double ParamSquareRoot(double Param1)
{
return Math.Sqrt(Param1);
}
/// <summary>
/// 实数的幂运算
/// </summary>
/// <param name="Param1">传入值实数1</param>
/// <param name="Param2">传入值实数1需要做几次方</param>
/// <example>Param1:3 Param22 返回值9</example>
/// <example>Param1:2 Param23 返回值8</example>
/// <example>Param1:5 Param24 返回值625</example>
/// <returns></returns>
public static double ParamPow(double Param1, double Param2)
{
return Math.Pow(Param1, Param2);
}
/// <summary>
/// 实数的绝对值
/// </summary>
/// <param name="Param1">传入值实数1</param>
/// <example>Param1:-3.7 返回值3.7</example>
/// <returns></returns>
public static double ParamAbs(double Param1)
{
return Math.Abs(Param1);
}
/// <summary>
/// 实数的向下取整
/// </summary>
/// <param name="Param1">传入值实数1</param>
/// <example>Param1:3.7 返回值3</example>
/// <returns></returns>
public static double ParamFloor(double Param1)
{
return Math.Floor(Param1);
}
/// <summary>
/// 实数的向上取整
/// </summary>
/// <param name="Param1">传入值实数1</param>
/// <example>Param1:3.7 返回值4</example>
/// <returns></returns>
public static double ParamCeiling(double Param1)
{
return Math.Ceiling(Param1);
}
#endregion
#region String类型的数据
/// <summary>
/// A与B转换为double后比较,返回A比较B的结果
/// </summary>
/// <param name="a">比较数1</param>
/// <param name="b">比较数2</param>
/// <param name="比较方法">比较方法</param>
/// <returns>返回A比较B</returns>
public static bool Comparison(string a, string b, ComparisonFuncEnum )
{
var aa = Convert.ToDouble(a);
var bb = Convert.ToDouble(b);
switch ()
{
case ComparisonFuncEnum.Big:
return aa > bb;
case ComparisonFuncEnum.BigOrEqual:
return aa >= bb;
case ComparisonFuncEnum.Small:
return aa < bb;
case ComparisonFuncEnum.SmallOrEqual:
return aa <= bb;
case ComparisonFuncEnum.Equal:
return aa == bb;
case ComparisonFuncEnum.NotEqual:
return aa != bb;
default:
return false;
}
}
/// <summary>
/// 加法指令,转换为double后返回o1+o2
/// </summary>
/// <param name="o1">运算数1</param>
/// <param name="o2">运算数2</param>
/// <returns>返回o1+o2</returns>
public static string TwoNumberAdd(string o1, string o2)
{
return (Convert.ToDecimal(o1) + Convert.ToDecimal(o2)).ToString();
}
/// <summary>
/// 减法指令,转换为double后返回o1-o2
/// </summary>
/// <param name="o1">运算数1</param>
/// <param name="o2">运算数2</param>
/// <returns>返回o1-o2</returns>
public static string TwoNumberReduce(string o1, string o2)
{
return (Convert.ToDecimal(o1) - Convert.ToDecimal(o2)).ToString();
}
/// <summary>
/// 乘法指令,转换为double后返回o1*o2
/// </summary>
/// <param name="o1">运算数1</param>
/// <param name="o2">运算数2</param>
/// <returns>返回o1*o2</returns>
public static string TwoNumberMult(string o1, string o2)
{
return (Convert.ToDecimal(o1) * Convert.ToDecimal(o2)).ToString();
}
/// <summary>
/// 除法指令,转换为double后返回o1/o2
/// </summary>
/// <param name="o1">运算数1</param>
/// <param name="o2">运算数2</param>
/// <returns>返回o1/o2</returns>
public static string TwoNumberDivide1(string o1, string o2)
{
return (Convert.ToDecimal(o1) / Convert.ToDecimal(o2)).ToString();
}
/// <summary>
/// 转换为double后返回o1/o2
/// </summary>
/// <param name="o1">运算数1</param>
/// <param name="o2">运算数2</param>
/// <param name="o3">保留几位小数</param>
/// <returns>返回o1/o2</returns>
public static string TwoNumberDivide2(string o1, string o2, int o3)
{
return (Math.Round((Convert.ToDecimal(o1) / Convert.ToDecimal(o2)), o3)).ToString();
}
/// <summary>
/// 返回o1%o2
/// </summary>
/// <param name="o1">运算数1</param>
/// <param name="o2">运算数2</param>
/// <returns>返回o1%o2</returns>
public static string TwoNumberRemainder(string o1, string o2)
{
return (Convert.ToDecimal(o1) % (Convert.ToDecimal(o2))).ToString();
}
/// <summary>
/// 计算两个数字的平方。
/// </summary>
/// <param name="o1">第一个数字的字符串表示。</param>
/// <param name="o2">第二个数字的字符串表示。</param>
/// <example>Param1:3 Param22 返回值9</example>
/// <example>Param1:2 Param23 返回值8</example>
/// <example>Param1:5 Param24 返回值625</example>
/// <returns>返回两个数字的平方的字符串表示。</returns>
public static string NumberPow(string o1, string o2)
{
// 将输入的字符串转换为双精度浮点数,并计算它们的平方
// 最后将结果转换为字符串并返回
return Math.Pow(Convert.ToDouble(o1), Convert.ToDouble(o2)).ToString();
}
/// <summary>
/// 计算一个数的平方根。
/// </summary>
/// <param name="o1">要计算平方根的数字的字符串表示。</param>
/// <returns>返回输入数字的平方根的字符串表示。</returns>
public static string NumberSqrt(string o1)
{
// 将输入的字符串转换为双精度浮点数,并计算其平方根。
// 最后将结果转换为字符串并返回。
return Math.Sqrt(Convert.ToDouble(o1)).ToString();
}
/// <summary>
/// 计算一个数的绝对值。
/// </summary>
/// <param name="o1">要计算绝对值的数字的字符串表示。</param>
/// <returns>返回输入数字的绝对值的字符串表示。</returns>
public static string NumberAbs(string o1)
{
// 将输入的字符串转换为双精度浮点数,并计算其绝对值。
// 最后将结果转换为字符串并返回。
return Math.Abs(Convert.ToDouble(o1)).ToString();
}
/// <summary>
/// 计算一个角度的正弦值。
/// </summary>
/// <param name="o1">要计算正弦值的角度的字符串表示(单位为弧度)。</param>
/// <returns>返回输入角度的正弦值的字符串表示。</returns>
public static string NumberSin(string o1)
{
// 将输入的字符串转换为双精度浮点数,并计算其正弦值。
// 最后将结果转换为字符串并返回。
return Math.Sin(Convert.ToDouble(o1)).ToString();
}
/// <summary>
/// 计算一个角度的余弦值。
/// </summary>
/// <param name="o1">要计算余弦值的角度的字符串表示(单位为弧度)。</param>
/// <returns>返回输入角度的余弦值的字符串表示。</returns>
public static string NumberCos(string o1)
{
// 将输入的字符串转换为双精度浮点数,并计算其余弦值。
// 最后将结果转换为字符串并返回。
return Math.Cos(Convert.ToDouble(o1)).ToString();
}
/// <summary>
/// 计算一个角度的正切值。
/// </summary>
/// <param name="o1">要计算正切值的角度的字符串表示(单位为弧度)。</param>
/// <returns>返回输入角度的正切值的字符串表示。</returns>
public static string NumberTan(string o1)
{
// 将输入的字符串转换为双精度浮点数,并计算其正切值。
// 最后将结果转换为字符串并返回。
return Math.Tan(Convert.ToDouble(o1)).ToString();
}
/// <summary>
/// 计算一个数的反正弦值。
/// </summary>
/// <param name="o1">要计算反正弦值的数的字符串表示。</param>
/// <returns>返回输入数的反正弦值的字符串表示(单位为弧度)。</returns>
public static string NumberASin(string o1)
{
// 将输入的字符串转换为双精度浮点数,并计算其反正弦值。
// 最后将结果转换为字符串并返回。
return Math.Asin(Convert.ToDouble(o1)).ToString();
}
/// <summary>
/// 计算一个数的反余弦值。
/// </summary>
/// <param name="o1">要计算反余弦值的数的字符串表示。</param>
/// <returns>返回输入数的反余弦值的字符串表示(单位为弧度)。</returns>
public static string NumberACos(string o1)
{
// 将输入的字符串转换为双精度浮点数,并计算其反余弦值。
// 最后将结果转换为字符串并返回。
return Math.Acos(Convert.ToDouble(o1)).ToString();
}
/// <summary>
/// 计算一个数的反正切值。
/// </summary>
/// <param name="o1">要计算反正切值的数的字符串表示。</param>
/// <returns>返回输入数的反正切值的字符串表示(单位为弧度)。</returns>
public static string NumberATan(string o1)
{
// 将输入的字符串转换为双精度浮点数,并计算其反正切值。
// 最后将结果转换为字符串并返回。
return Math.Atan(Convert.ToDouble(o1)).ToString();
}
/// <summary>
/// 计算 e 的给定次幂。
/// </summary>
/// <param name="o1">e 的指数的字符串表示。</param>
/// <returns>返回 e 的给定次幂的字符串表示。</returns>
public static string eIndex(string o1)
{
// 将输入的字符串转换为双精度浮点数,并计算 e 的给定次幂。
// 最后将结果转换为字符串并返回。
return Math.Exp(Convert.ToDouble(o1)).ToString();
}
/// <summary>
/// 计算一个数的自然对数。
/// </summary>
/// <param name="o1">要计算自然对数的数的字符串表示。</param>
/// <returns>返回输入数的自然对数的字符串表示。</returns>
public static string NumberNaturalLogarithm(string o1)
{
// 将输入的字符串转换为双精度浮点数,并计算其自然对数。
// 最后将结果转换为字符串并返回。
return Math.Log(Convert.ToDouble(o1)).ToString();
}
/// <summary>
/// 计算一个数在指定基数下的对数。
/// </summary>
/// <param name="o1">要计算对数的数的字符串表示。</param>
/// <param name="Base">对数的基数的字符串表示。</param>
/// <returns>返回输入数在指定基数下的对数的字符串表示。</returns>
public static string NumberLogarithm(string o1, string Base)
{
// 将输入的字符串转换为双精度浮点数,并计算其在指定基数下的对数。
// 最后将结果转换为字符串并返回。
return Math.Log(Convert.ToDouble(o1), Convert.ToDouble(Base)).ToString();
}
/// <summary>
/// 对输入数字进行四舍五入取整。
/// </summary>
/// <param name="n1">要进行取整操作的数字的字符串表示。</param>
/// <returns>返回经过四舍五入取整后的结果的字符串表示。</returns>
public static string NumberRoundToNearest(string n1)
{
// 将输入的字符串转换为双精度浮点数,并进行四舍五入取整。
// 最后将结果转换为字符串并返回。
return Math.Round(Convert.ToDouble(n1)).ToString();
}
/// <summary>
/// 对输入数字进行向上舍入取整。
/// </summary>
/// <param name="n1">要进行取整操作的数字的字符串表示。</param>
/// <returns>返回经过向上舍入取整后的结果的字符串表示。</returns>
public static string NumberRoundUp(string n1)
{
// 将输入的字符串转换为双精度浮点数,并进行向上舍入取整。
// 最后将结果转换为字符串并返回。
return Math.Ceiling(Convert.ToDouble(n1)).ToString();
}
/// <summary>
/// 对输入数字进行向下舍入取整。
/// </summary>
/// <param name="n1">要进行取整操作的数字的字符串表示。</param>
/// <returns>返回经过向下舍入取整后的结果的字符串表示。</returns>
public static string NumberRoundDown(string n1)
{
// 将输入的字符串转换为双精度浮点数,并进行向下舍入取整。
// 最后将结果转换为字符串并返回。
return Math.Floor(Convert.ToDouble(n1)).ToString();
}
/// <summary>
/// 获取圆周率π的字符串表示。
/// </summary>
/// <returns>返回圆周率π的字符串表示。</returns>
public static string PI()
{
// 返回圆周率π的字符串表示。
return Math.PI.ToString();
}
//public static Random random1 = new Random();
/// <summary>
/// 生成一个随机整数。
/// </summary>
/// <returns>返回生成的随机整数的字符串表示。</returns>
public static string RandomNumber_Int()
{
Random random = new Random();
// 使用随机数生成器生成一个随机整数,并将其转换为字符串表示。
return random.Next().ToString();
}
/// <summary>
/// 生成一个指定范围内的随机整数。
/// </summary>
/// <param name="最小">随机数生成范围的最小值。</param>
/// <param name="最大">随机数生成范围的最大值(不包含)。</param>
/// <returns>返回生成的指定范围内的随机整数的字符串表示。</returns>
public static string RandomNumber_RangeInt(int , int )
{
Random random = new Random();
// 使用随机数生成器生成一个指定范围内的随机整数,并将其转换为字符串表示。
return random.Next(, ).ToString();
}
/// <summary>
/// 生成一个随机小数。
/// </summary>
/// <returns>返回生成的随机小数的字符串表示。</returns>
public static string RandomNumber_Decimal()
{
Random random = new Random();
// 使用随机数生成器生成一个随机小数,并将其转换为字符串表示。
return random.NextDouble().ToString();
}
/// <summary>
/// 计算给定算式的结果。
/// </summary>
/// <param name="s">要计算的算式的字符串表示。</param>
/// <returns>返回计算结果的字符串表示。</returns>
public static string FormulaCalculation(string s)
{
// 创建一个 DataTable 实例来进行算式的计算。
DataTable dataTable = new DataTable();
// 使用 DataTable 的 Compute 方法计算给定的算式,并将结果转换为字符串表示。
return dataTable.Compute(s, "").ToString();
}
#endregion
}
}

View File

@ -0,0 +1,153 @@
using Common.Attributes;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Command
{
[ATSCommand]
public static class CommandRadixChange
{
#region
/// <summary>
/// 二进制 转换成 八进制
/// </summary>
/// <param name="Param1">传入值:字符类型</param>
/// <example>Param1:"101010" 返回值:"52"</example>
/// <returns></returns>
public static string TwoRadix_ConvertTo_EightRadix(string Param1)
{
return Convert.ToString(Convert.ToInt32(Param1, 2),8);
}
/// <summary>
/// 二进制 转换成 十进制
/// </summary>
/// <param name="Param1">传入值:字符类型</param>
/// <example>Param1:"101010" 返回值:"42"</example>
/// <returns></returns>
public static string TwoRadix_ConvertTo_TenRadix(string Param1)
{
return Convert.ToString(Convert.ToInt32(Param1, 2));
}
/// <summary>
/// 二进制 转换成 十六进制
/// </summary>
/// <param name="Param1">传入值:字符类型</param>
/// <example>Param1:"101010" 返回值:"2A"</example>
/// <returns></returns>
public static string TwoRadix_ConvertTo_SixteenRadix(string Param1)
{
return Convert.ToString(Convert.ToInt32(Param1, 2), 16);
}
/// <summary>
/// 八进制 转换成 二进制
/// </summary>
/// <param name="Param1">传入值:字符类型</param>
/// <example>Param1:"88" 返回值:"1001000"</example>
/// <returns></returns>
public static string EightRadix_ConvertTo_TwoRadix(string Param1)
{
return Convert.ToString(Convert.ToInt32(Param1, 8), 2);
}
/// <summary>
/// 八进制 转换成 十进制
/// </summary>
/// <param name="Param1">传入值:字符类型</param>
/// <example>Param1:"88" 返回值:"72"</example>
/// <returns></returns>
public static double EightRadix_ConvertTo_TenRadix(string Param1)
{
double Value = Convert.ToInt32(Param1, 8);
return Value;
}
/// <summary>
/// 八进制 转换成 十六进制
/// </summary>
/// <param name="Param1">传入值:字符类型</param>
/// <example>Param1:"88" 返回值:"48"</example>
/// <returns></returns>
public static string EightRadix_ConvertTo_SixteenRadix(string Param1)
{
return Convert.ToString(Convert.ToInt32(Param1, 8), 16);
}
/// <summary>
/// 十进制 转换成 二进制
/// </summary>
/// <param name="Param1">传入值:整型数值</param>
/// <example>Param1:60 返回值:"111100"</example>
/// <returns></returns>
public static string TenRadix_ConvertTo_TwoRadix(int Param1)
{
return Convert.ToString(Param1, 2);
}
/// <summary>
/// 十进制 转换成 八进制
/// </summary>
/// <param name="Param1">传入值:整型数值</param>
/// <example>Param1:60 返回值:"74"</example>
/// <returns></returns>
public static string TenRadix_ConvertTo_EightRadix(int Param1)
{
return Convert.ToString(Param1, 8);
}
/// <summary>
/// 十进制 转换成 十六进制
/// </summary>
/// <param name="Param1">传入值:整型数值</param>
/// <example>Param1:60 返回值:"3C"</example>
/// <returns></returns>
public static string TenRadix_ConvertTo_SixteenRadix(int Param1)
{
return Convert.ToString(Param1, 16);
}
/// <summary>
/// 十六进制 转换成 二进制
/// </summary>
/// <param name="Param1">传入值:字符类型</param>
/// <example>Param1:"6F" 返回值:"1101111"</example>
/// <returns></returns>
public static string SixteenRadix_ConvertTo_Radix2(string Param1)
{
return Convert.ToString(Convert.ToInt32(Param1, 16), 2);
}
/// <summary>
/// 十六进制 转换成 八进制
/// </summary>
/// <param name="Param1">传入值:字符类型</param>
/// <example>Param1:"6F" 返回值:"157"</example>
/// <returns></returns>
public static string SixteenRadix_ConvertTo_EightRadix8(string Param1)
{
return Convert.ToString(Convert.ToInt32(Param1, 16), 8);
}
/// <summary>
/// 十六进制 转换成 十进制
/// </summary>
/// <param name="Param1">传入值:字符类型</param>
/// <example>Param1:"6F" 返回值:"111"</example>
/// <returns></returns>
public static string SixteenRadix_ConvertTo_TenRadix(string Param1)
{
return Convert.ToString(Convert.ToInt32(Param1, 16));
}
#endregion
}
}

View File

@ -0,0 +1,196 @@
using Common.Attributes;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Command
{
[ATSCommand]
public static class CommandStringProcessing
{
///<summary>
///获取值
///</summary>
///<param name="obj">要获取的值。</param>
///returns>获取值(字符串)。</returns>
public static string GetValue(object obj)
{
return Convert.ToString(obj) ?? string.Empty;
}
/// <summary>
/// 在原字符串中查找指定字符的位置。
/// </summary>
/// <param name="str">要查找的字符串。</param>
/// <param name="findStr">要查找的字符。</param>
/// <returns>字符在字符串中的位置,如果未找到则返回 -1。</returns>
public static int FindStr(string str, string findStr)
{
return str.IndexOf(findStr);
}
/// <summary>
/// 将原字符串中的指定字符替换为新字符。
/// </summary>
/// <param name="str">要替换的字符串。</param>
/// <param name="ReplaceStr">要被替换的字符。</param>
/// <param name="ReplacedStr">替换后的新字符。</param>
/// <returns>替换后的字符串。</returns>
public static string ReplaceStr(string str, string ReplaceStr, string ReplacedStr)
{
return str.Replace(ReplaceStr, ReplacedStr);
}
/// <summary>
/// 从原字符串中移除指定位置开始的指定个数的字符。
/// </summary>
/// <param name="str">要操作的字符串。</param>
/// <param name="startLocation">开始移除字符的位置。</param>
/// <param name="removeQty">要移除的字符个数。</param>
/// <returns>移除后的字符串。</returns>
public static string RemoveStr(string str, int startLocation, int removeQty)
{
return str.Remove(startLocation, removeQty);
}
/// <summary>
/// 在原字符串的指定位置插入新字符串。
/// </summary>
/// <param name="str">要操作的字符串。</param>
/// <param name="startLocation">要插入字符串的位置。</param>
/// <param name="newStr">要插入的字符串。</param>
/// <returns>插入后的字符串。</returns>
public static string InsertStr(string str, int startLocation, string newStr)
{
return str.Insert(startLocation, newStr);
}
/// <summary>
/// 从原字符串中截取指定位置开始的指定个数的字符。
/// </summary>
/// <param name="str">要操作的字符串。</param>
/// <param name="startLocation">要截取的起始位置。</param>
/// <param name="qty">要截取的字符个数。</param>
/// <returns>截取后的字符串。</returns>
public static string CaptureStr(string str, int startLocation, int qty)
{
return str.Substring(startLocation, qty);
}
/// <summary>
/// 将字符串转换为小写形式。
/// </summary>
/// <param name="str">要转换的字符串。</param>
/// <returns>转换为小写后的字符串。</returns>
public static string StrConvertToLower(string str)
{
return str.ToLower();
}
/// <summary>
/// 将字符串转换为大写形式。
/// </summary>
/// <param name="str">要转换的字符串。</param>
/// <returns>转换为大写后的字符串。</returns>
public static string StrConvertToUpper(string str)
{
return str.ToUpper();
}
/// <summary>
/// 获取字符串的长度。
/// </summary>
/// <param name="str">要获取长度的字符串。</param>
/// <returns>字符串的长度。</returns>
public static int GetStrLength(string str)
{
return str.Length;
}
/// <summary>
/// 去除字符串两端的空白字符。
/// </summary>
/// <param name="str">要去除空白字符的字符串。</param>
/// <returns>去除空白字符后的字符串。</returns>
public static string StrRemoveLeadingAndTrailingWhitespaces(string str)
{
return str.Trim();
}
/// <summary>
/// 将字节数组转换为字符串,使用 UTF-8 编码。
/// </summary>
/// <param name="arr">要转换的字节数组。</param>
/// <returns>转换后的字符串。</returns>
public static string ByteArrayToStr_UTF8(byte[] arr)
{
return Encoding.UTF8.GetString(arr);
}
/// <summary>
/// 将字节数组转换为字符串,使用 GB18030 编码。
/// </summary>
/// <param name="arr">要转换的字节数组。</param>
/// <returns>转换后的字符串。</returns>
public static string ByteArrayToStr_GB18030(byte[] arr)
{
return Encoding.GetEncoding("gb18030").GetString(arr);
}
/// <summary>
/// 将字节数组转换为字符串,使用自选的编码类型。
/// </summary>
/// <param name="arr">要转换的字节数组。</param>
/// <param name="encodingType">要使用的编码类型。</param>
/// <returns>转换后的字符串。</returns>
public static string ByteArrayToStr_SelfSelectedEncoding(byte[] arr, string encodingType)
{
return Encoding.GetEncoding(encodingType).GetString(arr);
}
/// <summary>
/// 将字节数组转换为16进制字符串
/// </summary>
/// <param name="str">要转换的字节数组。</param>
/// <returns>转换后的字符串。</returns>
public static string ByteArrayTo_HexStr(byte[] str)
{
return Convert.ToInt32(str.ToString(),2).ToString("X2");
}
/// <summary>
/// 将字符串转换为字节数组,使用 UTF-8 编码。
/// </summary>
/// <param name="str">要转换的字符串。</param>
/// <returns>转换后的字节数组。</returns>
public static byte[] StrToByteArray_UTF8(string str)
{
return Encoding.UTF8.GetBytes(str);
}
/// <summary>
/// 将字符串转换为字节数组,使用 GB18030 编码。
/// </summary>
/// <param name="str">要转换的字符串。</param>
/// <returns>转换后的字节数组。</returns>
public static byte[] StrToByteArray_GB18030(string str)
{
return Encoding.GetEncoding("gb18030").GetBytes(str);
}
/// <summary>
/// 将字符串转换为字节数组,使用自选的编码类型。
/// </summary>
/// <param name="str">要转换的字符串。</param>
/// <param name="encodingType">要使用的编码类型。</param>
/// <returns>转换后的字节数组。</returns>
public static byte[] StrToByteArray_SelfSelectedEncoding(string str, string encodingType)
{
return Encoding.GetEncoding(encodingType).GetBytes(str);
}
}
}

463
Command/CommandSystem.cs Normal file
View File

@ -0,0 +1,463 @@
using Common.Attributes;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Command
{
[ATSCommand]
public static class CommandSystem
{
#region
/// <summary>
/// int转化为double
/// </summary>
/// <param name="Param1">传入值:整型数值</param>
/// <example>Param1:40 返回值40</example>
/// <returns></returns>
public static double Int_ConvertTo_Double(int Param1)
{
return Convert.ToDouble(Param1);
}
/// <summary>
/// double转化为Int16
/// </summary>
/// <param name="Param1">传入值:实数数值</param>
/// <example>Param1:4 返回值4</example>
/// <example>Param1:4.67 返回值4</example>
/// <returns></returns>
public static Int16 Double_ConvertTo_Int16(double Param1)
{
Int16 Value = Convert.ToInt16(Param1);
return Value;
}
/// <summary>
/// double转化为int,即Int32
/// </summary>
/// <param name="Param1">传入值:实数数值</param>
/// <example>Param1:4 返回值4</example>
/// <example>Param1:4.67 返回值4</example>
/// <returns></returns>
public static int Double_ConvertTo_Int(double Param1)
{
int Value = Convert.ToInt32(Param1);
return Value;
}
/// <summary>
/// double转化为Int64
/// </summary>
/// <param name="Param1">传入值:实数数值</param>
/// <example>Param1:4 返回值4</example>
/// <example>Param1:4.67 返回值4</example>
/// <returns></returns>
public static Int64 Double_ConvertTo_Int64(double Param1)
{
Int64 Value = Convert.ToInt64(Param1);
return Value;
}
/// <summary>
/// float转化为double
/// </summary>
/// <param name="Param1">传入值:浮点数值</param>
/// <example>Param1:4.0 返回值4</example>
/// <example>Param1:4.2 返回值4.2</example>
/// <returns></returns>
public static double Float_ConvertTo_Double(float Param1)
{
double Value = Convert.ToDouble(Param1);
return Value;
}
/// <summary>
/// 判断string转化为int转换成功返回 true失败返回 false
/// </summary>
/// <param name="Param1">传入值:字符串</param>
/// <example>Param1:"2" 返回值true</example>
/// <example>Param1:"abc" 返回值false</example>
/// <returns></returns>
public static bool BoolString_ConvertTo_Int(string Param1)
{
bool Value = int.TryParse(Param1, out int intValue);
return Value;
}
/// <summary>
/// string转化为int
/// </summary>
/// <param name="Param1">传入值:字符串</param>
/// <example>Param1:"2" 返回值2</example>
/// <returns></returns>
public static int String_ConvertTo_Int(string Param1)
{
int Value = Convert.ToInt32(Param1);
return Value;
}
/// <summary>
/// int转化为string
/// </summary>
/// <param name="Param1">传入值:整型数值</param>
/// <example>Param1:2 返回值:"2"</example>
/// <returns></returns>
public static string Int_ConvertTo_String(int Param1)
{
string Value = Convert.ToString(Param1);
return Value;
}
/// <summary>
/// 判断string转化为double转换成功返回 true失败返回 false
/// </summary>
/// <param name="Param1">传入值:字符串</param>
/// <example>Param1:"2" 返回值true</example>
/// <example>Param1:"2.1" 返回值true</example>
/// <example>Param1:"abc" 返回值false</example>
/// <returns></returns>
public static bool BoolString_ConvertTo_Double(string Param1)
{
bool Value = double.TryParse(Param1, out double intValue);
return Value;
}
/// <summary>
/// string转化为double
/// </summary>
/// <param name="Param1">传入值:字符串</param>
/// <example>Param1:"2" 返回值2</example>
/// <example>Param1:"2.1" 返回值2.1</example>
/// <returns></returns>
public static double String_ConvertTo_Double(string Param1)
{
double Value = Convert.ToDouble(Param1);
return Value;
}
/// <summary>
/// double转化为string
/// </summary>
/// <param name="Param1">传入值:实数数值</param>
/// <example>Param1:2 返回值:"2"</example>
/// <example>Param1:2.1 返回值:"2.1"</example>
/// <returns></returns>
public static string Double_ConvertTo_String(double Param1)
{
string Value = Convert.ToString(Param1);
return Value;
}
/// <summary>
/// float转化为string
/// </summary>
/// <param name="Param1">传入值:浮点数值</param>
/// <example>Param1:2.0 返回值:"2.0"</example>
/// <example>Param1:2.1 返回值:"2.1"</example>
/// <returns></returns>
public static string Float_ConvertTo_String(float Param1)
{
string Value = Convert.ToString(Param1);
return Value;
}
/// <summary>
/// 判断string转化为datetime转换成功返回 true失败返回 false
/// </summary>
/// <param name="Param1">传入值:时间字符串</param>
/// <example>Param1:"2025-08-14" 返回值true</example>
/// <example>Param1:"2025-08-14 13:14:15" 返回值true</example>
/// <example>Param1:"abc" 返回值false</example>
/// <returns></returns>
public static bool BoolString_ConvertTo_Datetime(string Param1)
{
bool Value = DateTime.TryParse(Param1, out DateTime DateTimeValue);
return Value;
}
/// <summary>
/// string转化为datetime
/// </summary>
/// <param name="Param1">传入值:时间字符串</param>
/// <example>Param1:"2025-08-14" 返回值2025/8/14 0:00:00</example>
/// <example>Param1:"2025-08-14 13:14:15" 返回值2025/8/14 13:14:15</example>
/// <returns></returns>
public static DateTime String_ConvertTo_Datetime(string Param1)
{
DateTime Value = Convert.ToDateTime(Param1);
return Value;
}
/// <summary>
/// datetime转化为string
/// </summary>
/// <param name="Param1">传入值:时间</param>
/// <example>Param1:2025/8/14 13:14:15 返回值:"2025/08/14 13:14:15"</example>
/// <returns></returns>
public static string Datetime_ConvertTo_String1(DateTime Param1)
{
string Value = Convert.ToString(Param1);
return Value;
}
/// <summary>
/// datetime转化为string
/// </summary>
/// <param name="Param1">传入值:时间</param>
/// <param name="DateTimeFormat">传入值:字符串时间格式</param>
/// <example>Param1:2025/8/14 13:14:15 DateTimeFormat:"yyyy-MM-dd" 返回值:"2025-08-14"</example>
/// <example>Param1:2025/8/14 13:14:15 DateTimeFormat:"yyyy-MM-dd hh:mm:ss" 返回值:"2025-08-14 01:14:15"</example>
/// <example>Param1:2025/8/14 13:14:15 DateTimeFormat:"yyyy-MM-dd HH:mm:ss" 返回值:"2025-08-14 13:14:15"</example>
/// <example>Param1:2025/8/14 13:14:15 DateTimeFormat:"yyyyMMdd" 返回值:"20250814"</example>
/// <returns></returns>
public static string Datetime_ConvertTo_String2(DateTime Param1,string DateTimeFormat)
{
string Value = Param1.ToString(DateTimeFormat);
return Value;
}
/// <summary>
/// bool转化为string
/// </summary>
/// <param name="Param1">传入值:布尔值</param>
/// <example>Param1:true 返回值:"true"</example>
/// <example>Param1:false 返回值:"false"</example>
/// <returns></returns>
public static string Bool_ConvertTo_String(bool Param1)
{
string Value = Convert.ToString(Param1);
return Value;
}
/// <summary>
/// string转化为bool
/// </summary>
/// <param name="Param1">传入值:字符串</param>
/// <example>Param1:"true" 返回值true</example>
/// <example>Param1:"false" 返回值false</example>
/// <example>Param1:"abc" 返回值false</example>
/// <returns></returns>
public static bool String_ConvertTo_Bool(string Param1)
{
bool Value = bool.TryParse(Param1, out bool boolValue);
return Value;
}
/// <summary>
/// 将无符号整型转换为整型
/// </summary>
/// <param name="u"></param>
/// <returns></returns>
public static int Uint_ConvertTo_Int(uint u)
{
return (int)u;
}
/// <summary>
/// 将对象转换为字符串
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string Object_ConvertTo_String(object obj)
{
return Convert.ToString(obj);
}
/// <summary>
/// 将字符串内容转换为byte
/// </summary>
/// <param name="s">要转换的内容</param>
/// <returns></returns>
public static byte String_ConvertTo_Byte(string s)
{
return Convert.ToByte(s);
}
/// <summary>
/// 转换为short(int16)
/// </summary>
/// <param name="s">要转换的内容</param>
/// <returns></returns>
public static short String_ConvertTo_Short(string s)
{
return Convert.ToInt16(s);
}
/// <summary>
/// 将字符串转换为无符号整数。
/// </summary>
/// <param name="s">要转换的字符串。</param>
/// <returns>转换后的无符号整数。</returns>
public static uint String_ConvertTo_Uint(string s)
{
return Convert.ToUInt32(s);
}
/// <summary>
/// 将指定进制的字符串转换为整数。
/// </summary>
/// <param name="s">要转换的字符串。</param>
/// <param name="XRadix">源字符串的进制。只能为2,8,10,16</param>
/// <returns>转换后的整数。</returns>
public static int XRadixString_ConvertTo_Int(string s, int XRadix)
{
return Convert.ToInt32(s, XRadix);
}
#endregion
#region
/// <summary>
/// 执行整数的异或操作。
/// </summary>
/// <param name="a">第一个整数。</param>
/// <param name="b">第二个整数。</param>
/// <returns>异或操作结果。</returns>
public static int XOR(int a, int b)
{
return a ^ b;
}
/// <summary>
/// 执行整数的位或操作。
/// </summary>
/// <param name="a">第一个整数。</param>
/// <param name="b">第二个整数。</param>
/// <returns>位或操作结果。</returns>
public static int BitwiseOR(int a, int b)
{
return a | b;
}
/// <summary>
/// 执行整数的位与操作。
/// </summary>
/// <param name="a">第一个整数。</param>
/// <param name="b">第二个整数。</param>
/// <returns>位与操作结果。</returns>
public static int BitwiseAND(int a, int b)
{
return a & b;
}
/// <summary>
/// 将整数向左移动指定位数。
/// </summary>
/// <param name="a">要移动的整数。</param>
/// <param name="BitwiseLeftShift">左移的位数。</param>
/// <returns>移动后的结果。</returns>
public static int LeftShift(int a, int BitwiseLeftShift)
{
return a << BitwiseLeftShift;
}
/// <summary>
/// 将整数向右移动指定位数。
/// </summary>
/// <param name="a">要移动的整数。</param>
/// <param name="BitwiseRightShift">右移的位数。</param>
/// <returns>移动后的结果。</returns>
public static int RightShift(int a, int BitwiseRightShift)
{
return a >> BitwiseRightShift;
}
/// <summary>
/// 执行逻辑或操作。
/// </summary>
/// <param name="a">第一个逻辑值。</param>
/// <param name="b">第二个逻辑值。</param>
/// <returns>逻辑或操作结果。</returns>
public static bool LogicalOR(bool a, bool b)
{
return a || b;
}
/// <summary>
/// 执行逻辑与操作。
/// </summary>
/// <param name="a">第一个逻辑值。</param>
/// <param name="b">第二个逻辑值。</param>
/// <returns>逻辑与操作结果。</returns>
public static bool LogicalAND(bool a, bool b)
{
return a && b;
}
/// <summary>
/// 将字节的高低位对调。
/// </summary>
/// <param name="b">要对调的字节。</param>
/// <returns>对调后的字节。</returns>
public static byte ByteHighAndLowBitSwap(byte b)
{
return (byte)(((b & 0x0F) << 4) | ((b & 0xF0) >> 4));
}
/// <summary>
/// 翻转字节数组中的元素顺序。
/// </summary>
/// <param name="b">要翻转的字节数组。</param>
/// <returns>翻转后的字节数组。</returns>
public static byte[] ByteArrayReverse(byte[] b)
{
return b.Reverse().ToArray();
}
/// <summary>
/// 将当前线程挂起指定的时间。
/// </summary>
/// <param name="time">要延时的时间,以毫秒为单位。</param>
public static void Delay_ms(int time)
{
Thread.Sleep(time);
}
/// <summary>
/// 将当前线程挂起指定的时间。
/// </summary>
/// <param name="time">要延时的时间,以秒为单位。</param>
public static void Delay_s(int time)
{
Thread.Sleep(time * 1000);
}
/// <summary>
/// 将当前线程挂起指定的时间。
/// </summary>
/// <param name="time">要延时的时间,以分钟为单位。</param>
public static void Delay_min(int time)
{
Thread.Sleep(time * 1000 * 60);
}
/// <summary>
/// 将当前线程挂起指定的时间。
/// </summary>
/// <param name="time">要延时的时间,以小时为单位。</param>
public static void Delay_hour(int time)
{
Thread.Sleep(time * 1000 * 60 * 60);
}
/// <summary>
/// 将当前线程挂起指定的时间。
/// </summary>
/// <param name="time">要延时的时间,以天为单位。</param>
public static void Delay_day(int time)
{
Thread.Sleep(time * 1000 * 60 * 60 * 24);
}
#endregion
#region
#endregion
}
}

95
Command/CommandTime.cs Normal file
View File

@ -0,0 +1,95 @@
using Common.Attributes;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Command
{
[ATSCommand]
public static class CommandTime
{
#region
/// <summary>
/// 获取给定时间段的总毫秒数。
/// </summary>
/// <param name="TimePeriod">要获取总毫秒数的时间段。</param>
/// <returns>返回时间段的总毫秒数。</returns>
public static double GetTimePeriodMilliseconds(TimeSpan TimePeriod)
{
// 返回时间段的总毫秒数。
return TimePeriod.TotalMilliseconds;
}
/// <summary>
/// 获取给定时间段的总秒数。
/// </summary>
/// <param name="TimePeriod">要获取总秒数的时间段。</param>
/// <returns>返回时间段的总秒数。</returns>
public static double GetTimePeriodSeconds(TimeSpan TimePeriod)
{
// 返回时间段的总秒数。
return TimePeriod.TotalSeconds;
}
/// <summary>
/// 获取给定时间段的总分钟数。
/// </summary>
/// <param name="TimePeriod">要获取总分钟数的时间段。</param>
/// <returns>返回时间段的总分钟数。</returns>
public static double GetTimePeriodMinutes(TimeSpan TimePeriod)
{
// 返回时间段的总分钟数。
return TimePeriod.TotalMinutes;
}
/// <summary>
/// 获取给定时间段的总小时数。
/// </summary>
/// <param name="TimePeriod">要获取总小时数的时间段。</param>
/// <returns>返回时间段的总小时数。</returns>
public static double GetTimePeriodHours(TimeSpan TimePeriod)
{
// 返回时间段的总小时数。
return TimePeriod.TotalHours;
}
/// <summary>
/// 获取给定时间段的总天数。
/// </summary>
/// <param name="TimePeriod">要获取总天数的时间段。</param>
/// <returns>返回时间段的总天数。</returns>
public static double GetTimePeriodDays(TimeSpan TimePeriod)
{
// 返回时间段的总天数。
return TimePeriod.TotalDays;
}
/// <summary>
/// 计算两个日期时间之间的时间差。
/// </summary>
/// <param name="date1">第一个日期时间。</param>
/// <param name="date2">第二个日期时间。</param>
/// <returns>返回两个日期时间之间的时间差。</returns>
public static TimeSpan GetDateReduce(DateTime date1, DateTime date2)
{
// 返回第一个日期时间减去第二个日期时间的时间差。
return date1 - date2;
}
/// <summary>
/// 获取当前系统时间。
/// </summary>
/// <returns>返回当前系统时间。</returns>
public static DateTime GetNowTime()
{
// 返回当前系统时间。
return DateTime.Now;
}
#endregion
}
}

58
Command/Delay.cs Normal file
View File

@ -0,0 +1,58 @@
using Common.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Command
{
[ATSCommand]
public static class Delay
{
/// <summary>
/// 等待_毫秒
/// </summary>
/// <param name="millisecond"></param>
/// <param name="ct"></param>
/// <returns></returns>
public static async Task Delay_ms(int millisecond, CancellationToken ct)
{
await Task.Delay(millisecond, ct);
}
/// <summary>
/// 等待_秒
/// </summary>
/// <param name="second"></param>
/// <param name="ct"></param>
/// <returns></returns>
public static async Task Delay_s(float second, CancellationToken ct)
{
await Task.Delay((int)second * 1000, ct);
}
/// <summary>
/// 等待_分钟
/// </summary>
/// <param name="minnute"></param>
/// <param name="ct"></param>
/// <returns></returns>
public static async Task Delay_m(float minnute, CancellationToken ct)
{
await Task.Delay((int)minnute * 60 * 1000, ct);
}
/// <summary>
/// 等待_小时
/// </summary>
/// <param name="minnute"></param>
/// <param name="ct"></param>
/// <returns></returns>
public static async Task Delay_h(float minnute, CancellationToken ct)
{
await Task.Delay((int)minnute * 60 * 1000, ct);
}
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Common.Attributes
{
/// <summary>
/// 标记可加载到指令集中的类或方法
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public sealed class ATSCommandAttribute : Attribute
{
/// <summary>
/// 指令描述(用于工具提示)
/// </summary>
public string Description { get; }
/// <summary>
/// 指令分类(用于树形视图分组)
/// </summary>
public string Category { get; set; } = "默认分类";
public ATSCommandAttribute() { }
public ATSCommandAttribute(string description)
{
Description = description;
}
}
}

View File

@ -24,7 +24,7 @@ namespace Logger
foreach (var line in lines) foreach (var line in lines)
{ {
// 匹配你项目的命名空间路径 // 匹配你项目的命名空间路径
if (line.Contains("BaseFrame")) if (line.Contains("BOB"))
{ {
// 提取 "in 文件路径:line 行号" // 提取 "in 文件路径:line 行号"
var match = Regex.Match(line, @"in (.+?):line (\d+)"); var match = Regex.Match(line, @"in (.+?):line (\d+)");