TemplateBase.cs文件相关内容

本文介绍了如何通过修改CodeSmith核心文件TemplateBase.cs来定制自己的模板。重点讲解了添加新模板MyTest.cst所需的三个关键步骤,并强调了这些修改对于模板正常工作的必要性。
<p>TemplateBase.cs是CodeSmith的核心,要编写高质量的模板必须先要了解其中的内容
这里我简单说一下:要添加一个MyTest.cst模板需要在TemplateBase.cs中注意修改的3个地方:
1.</p>
<pre class="csharp" name="code"> #region Enumerations

public enum ObjectType

{

<font color="#ff0000"> MyTest,
</font>
EditableRoot,

EditableRootList,

EditableChild,

EditableChildList,

EditableSwitchable,

NameValueList,

ReadOnlyRoot,

ReadOnlyRootList,

ReadOnlyChild,

ReadOnlyChildList

}</pre>

2.
<pre class="csharp" name="code"> public class TemplateHelper

{

private TemplateHelper() { }


public static bool IsObjectType(ICodeTemplateInfo info)

{

switch (info.FileName.ToLower())

{

<font color="#ff0000">case "mytest.cst":
</font>3.<pre class="csharp" name="code"> public static ObjectType ToObjectType(ICodeTemplateInfo info)

{

switch (info.FileName.ToLower())

{

<font color="#ff0000">case "mytest.cst": return ObjectType.MyTest;
</font>
case "editableroot.cst": return ObjectType.EditableRoot;

case "editablerootlist.cst": return ObjectType.EditableRootList;</pre>
<pre class="csharp" name="code">否则生成的时候会报错,提示不能生成业务类型</pre>
</pre>
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build WORKDIR /src COPY ["src/Ctg.Template.Web.Host/Ctg.Template.Web.Host.csproj", "src/Ctg.Template.Web.Host/"] COPY ["src/Ctg.Template.Web.Core/Ctg.Template.Web.Core.csproj", "src/Ctg.Template.Web.Core/"] COPY ["src/Ctg.Template.Application/Ctg.Template.Application.csproj", "src/Ctg.Template.Application/"] COPY ["src/Ctg.Template.Application.Shared/Ctg.Template.Application.Shared.csproj", "src/Ctg.Template.Application.Shared/"] COPY ["src/Ctg.Template.Core.Shared/Ctg.Template.Core.Shared.csproj", "src/Ctg.Template.Core.Shared/"] COPY ["src/Ctg.Template.Core/Ctg.Template.Core.csproj", "src/Ctg.Template.Core/"] COPY ["src/Ctg.Template.EntityFrameworkCore/Ctg.Template.EntityFrameworkCore.csproj", "src/Ctg.Template.EntityFrameworkCore/"] COPY ["src/Ctg.Template.GraphQL/Ctg.Template.GraphQL.csproj", "src/Ctg.Template.GraphQL/"] RUN dotnet restore "src/Ctg.Template.Web.Host/Ctg.Template.Web.Host.csproj" COPY . . WORKDIR "/src/src/Ctg.Template.Web.Host" RUN dotnet build "Ctg.Template.Web.Host.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "Ctg.Template.Web.Host.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "Ctg.Template.Web.Host.dll"]
11-29
以下是简化后的C#窗体应用项目结构,完全按照Visual Studio新建项目的默认结构设计: ``` DataParserApp/ ├── DataParserApp.csproj ├── Program.cs ├── Properties/ │ └── AssemblyInfo.cs ├── Resources/ │ └── Rules.xml ├── MainForm.cs ├── MainForm.Designer.cs └── ProtocolParser.cs ``` ### 1. DataParserApp.csproj (项目文件) ```xml <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net472</TargetFramework> <UseWindowsForms>true</UseWindowsForms> </PropertyGroup> <ItemGroup> <None Include="Resources\Rules.xml"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> </Project> ``` ### 2. Program.cs (程序入口) ```csharp using System; using System.Windows.Forms; namespace DataParserApp { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } } } ``` ### 3. Resources/Rules.xml (规则配置文件) ```xml <?xml version="1.0" encoding="utf-8"?> <DataDefinitions> <Template Command="0x01" SubCommand="0x00"> <Fields> <Field Name="Current" Offset="2" Type="float" Coefficient="0.1" /> <Field Name="Voltage" Offset="6" Type="float" Coefficient="0.01" /> <Field Name="Temp" Offset="10" Type="int16" Coefficient="0.5" /> </Fields> <Flags> <Flag Name="SystemFault" Offset="12"> <Bit Pos="0" Desc="过流" /> <Bit Pos="1" Desc="过压" /> <Bit Pos="2" Desc="过温" /> </Flag> </Flags> </Template> </DataDefinitions> ``` ### 4. MainForm.cs (主窗体逻辑) ```csharp using System; using System.Windows.Forms; namespace DataParserApp { public partial class MainForm : Form { private ProtocolParser parser; public MainForm() { InitializeComponent(); parser = new ProtocolParser("Resources\\Rules.xml"); parser.DataParsed += UpdateDisplay; parser.FaultDetected += ShowFault; } private void UpdateDisplay(object sender, DataEventArgs e) { if (InvokeRequired) { Invoke(new Action<object, DataEventArgs>(UpdateDisplay), sender, e); return; } Controls[$"txt{e.Name}"].Text = e.Value.ToString("F2"); } private void ShowFault(object sender, FaultEventArgs e) { MessageBox.Show($"故障:{e.Description}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); } private void btnSend_Click(object sender, EventArgs e) { byte[] testData = new byte[13]; testData[0] = 0x01; // 命令字 testData[1] = 0x00; // 子命令 // 电流值 100A (原始值1000) BitConverter.GetBytes(1000).CopyTo(testData, 2); // 电压值 220V (原始值22000) BitConverter.GetBytes(22000).CopyTo(testData, 6); // 温度值 30℃ (原始值60) BitConverter.GetBytes((short)60).CopyTo(testData, 10); // 故障标志 (过温) testData[12] = 0x04; parser.Parse(testData); } } } ``` ### 5. MainForm.Designer.cs (窗体设计器) ```csharp namespace DataParserApp { partial class MainForm { private System.ComponentModel.IContainer components = null; public System.Windows.Forms.TextBox txtCurrent; public System.Windows.Forms.TextBox txtVoltage; public System.Windows.Forms.TextBox txtTemp; public System.Windows.Forms.Button btnSend; protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(300, 200); // 创建文本框 this.txtCurrent = new TextBox() { Location = new System.Drawing.Point(100, 10), Width = 100 }; this.txtVoltage = new TextBox() { Location = new System.Drawing.Point(100, 40), Width = 100 }; this.txtTemp = new TextBox() { Location = new System.Drawing.Point(100, 70), Width = 100 }; // 创建按钮 this.btnSend = new Button() { Text = "发送数据", Location = new System.Drawing.Point(100, 110) }; this.btnSend.Click += btnSend_Click; // 添加控件 this.Controls.Add(new Label() { Text = "电流:", Location = new System.Drawing.Point(20, 10) }); this.Controls.Add(txtCurrent); this.Controls.Add(new Label() { Text = "电压:", Location = new System.Drawing.Point(20, 40) }); this.Controls.Add(txtVoltage); this.Controls.Add(new Label() { Text = "温度:", Location = new System.Drawing.Point(20, 70) }); this.Controls.Add(txtTemp); this.Controls.Add(btnSend); } } } ``` ### 6. ProtocolParser.cs (协议解析器) ```csharp using System; using System.Xml.Serialization; using System.IO; namespace DataParserApp { public class ProtocolParser { private Template template; public event EventHandler<DataEventArgs> DataParsed; public event EventHandler<FaultEventArgs> FaultDetected; public ProtocolParser(string rulePath) { LoadRules(rulePath); } private void LoadRules(string path) { if (!File.Exists(path)) return; var serializer = new XmlSerializer(typeof(Template)); using (var reader = new StreamReader(path)) { template = (Template)serializer.Deserialize(reader); } } public void Parse(byte[] data) { if (data.Length < 2 || template == null) return; string cmd = data[0].ToString("X2"); string subCmd = data[1].ToString("X2"); if (cmd != template.Command || subCmd != template.SubCommand) return; ParseData(data); ParseFlags(data); } private void ParseData(byte[] data) { foreach (var field in template.Fields) { if (field.Offset + GetSize(field.Type) > data.Length) continue; dynamic value = null; switch (field.Type.ToLower()) { case "int16": value = BitConverter.ToInt16(data, field.Offset); break; case "int32": value = BitConverter.ToInt32(data, field.Offset); break; case "float": value = BitConverter.ToSingle(data, field.Offset); break; } OnDataParsed(new DataEventArgs(field.Name, value * field.Coefficient)); } } private void ParseFlags(byte[] data) { foreach (var flag in template.Flags) { if (flag.Offset >= data.Length) continue; byte flagByte = data[flag.Offset]; foreach (var bit in flag.Bits) { if ((flagByte & (1 << bit.Pos)) != 0) OnFaultDetected(new FaultEventArgs(bit.Desc)); } } } private int GetSize(string type) { switch (type.ToLower()) { case "int16": return 2; case "int32": return 4; case "float": return 4; default: return 0; } } protected virtual void OnDataParsed(DataEventArgs e) { DataParsed?.Invoke(this, e); } protected virtual void OnFaultDetected(FaultEventArgs e) { FaultDetected?.Invoke(this, e); } } // 数据模型类 [XmlRoot("Template")] public class Template { [XmlAttribute("Command")] public string Command { get; set; } [XmlAttribute("SubCommand")] public string SubCommand { get; set; } [XmlArray("Fields"), XmlArrayItem("Field")] public Field[] Fields { get; set; } = new Field[0]; [XmlArray("Flags"), XmlArrayItem("Flag")] public Flag[] Flags { get; set; } = new Flag[0]; } public class Field { [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("Offset")] public int Offset { get; set; } [XmlAttribute("Type")] public string Type { get; set; } [XmlAttribute("Coefficient")] public float Coefficient { get; set; } } public class Flag { [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("Offset")] public int Offset { get; set; } [XmlElement("Bit")] public Bit[] Bits { get; set; } = new Bit[0]; } public class Bit { [XmlAttribute("Pos")] public int Pos { get; set; } [XmlAttribute("Desc")] public string Desc { get; set; } } // 事件参数类 public class DataEventArgs : EventArgs { public string Name { get; } public float Value { get; } public DataEventArgs(string name, float value) { Name = name; Value = value; } } public class FaultEventArgs : EventArgs { public string Description { get; } public FaultEventArgs(string description) { Description = description; } } } ```文本框没有内容显示
07-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值