C# TEKLA STRUCTURES 2022 二次开发 开发环境搭建

初步接触二次TEKLA,以下仅为个人观点

使用的exe方式开发的

引用的nuget包

程序入口点稍作处理,开启了TEKLA 软件才能启动本程序,TEKLA软件关闭,本程序退出

internal static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
try
{
if (TeklaStructures.Connect())
{
TeklaStructures.Closed += (s, e) =>
{
Interaction.MsgBox("Tekla Structures程序已经退出!", MsgBoxStyle.OkOnly | MsgBoxStyle.Critical);
Application.Exit();
};
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
else
{
Interaction.MsgBox("请先保证Tekla软件已经被启动!", MsgBoxStyle.OkOnly | MsgBoxStyle.Critical);
Application.Exit();
}
}
catch (Exception ex)
{
Interaction.MsgBox(ex.StackTrace, MsgBoxStyle.OkOnly | MsgBoxStyle.Critical);
}
}
}

主窗口采用反射搭建一个 固定的界面

效果如下

 

 

 

反射的特性标签自己定义的如下

public class MyTeklaCmdAtt : Attribute
{
public string ImageName { get; set; }
public string ButtonName { get; set; }
public string CategoryName { get; set; }
public string HelpString { get; set; }
public MyTeklaCmdAtt(string _category, string _cmdName, string helpStr = "", string _img = "")
{
this.ImageName = _img;
this.ButtonName = _cmdName;
this.CategoryName = _category;
this.HelpString = helpStr;
}
}

主界面代码如下

public partial class MainForm : ApplicationFormBase
{
public static Model MyModel { get; set; }
public static ModelInfo ModelInfo => MyModel?.GetInfo();
public MainForm()
{
this.InitializeComponent();
if (MyModel == null) MyModel = new Model();
base.AutoSize = true;
base.InitializeForm();
base.Size = this.Size;
base.Text = Application.ProductName + $"({ModelInfo.ModelName})";
Dialogs.SetSettings(string.Empty);
TeklaStructures.MainWindow.AttachChildForm(this);
//AllocConsole();
}
private void Form1_Load(object sender, EventArgs e)
{
var cls = System.Reflection.Assembly.GetExecutingAssembly().GetTypes().Where(c => c.IsClass && c.IsPublic);
var Cmdmis = new List<MethodInfo>();
foreach (var item in cls)
{
var mis = item.GetMethods().Where(m => m.IsPublic && m.IsStatic && m.GetCustomAttribute(typeof(MyTeklaCmdAtt)) != null);
if (!mis.Any()) continue;
Cmdmis.AddRange(mis.ToArray());
}
Dictionary<string, List<MethodInfo>> dicts = Cmdmis.GroupBy(m => m.DeclaringType.Name).ToDictionary(c => c.Key, c => c.ToList());
foreach (var item in dicts)
{
var tabPage = new TabPage()
{
//Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right,
Text = item.Key,
Name = $"tbPage_{item.Key}",
BorderStyle = BorderStyle.Fixed3D,
BackColor = Color.AliceBlue,
//AutoSizeMode = AutoSizeMode.GrowOnly,
//AutoSize = true
};
var clsFlowLayoutPanel = new FlowLayoutPanel
{
Name = $"flwPan_{item.Key}",
FlowDirection = FlowDirection.TopDown,
Padding = new Padding(3),
BorderStyle = BorderStyle.FixedSingle,
AutoSize = true,
Parent = tabPage,
Dock = DockStyle.Fill,
AutoScroll = true,
WrapContents = true
};
tabPage.Controls.Add(clsFlowLayoutPanel);
foreach (var mi in item.Value)
{
var att = mi.GetCustomAttribute<MyTeklaCmdAtt>();
var btn = new Button()
{
Name = $"btn_{att.ButtonName}",
Text = att.ButtonName,
FlatStyle = FlatStyle.Popup,
AutoSize = true
};
var tt1 = new System.Windows.Forms.ToolTip
{
IsBalloon = true,
BackColor = Color.LightYellow,
UseAnimation = true,
};
tt1.SetToolTip(btn, att.HelpString);
btn.Click += (s1, e1) =>
{
try
{
var frm = mi.GetParameters().FirstOrDefault();
mi.Invoke(null, (frm==null?null:new object[] { this }));
}
catch (Exception ex)
{
Interaction.MsgBox(ex.StackTrace, MsgBoxStyle.OkOnly | MsgBoxStyle.Exclamation);
}
};
clsFlowLayoutPanel.Controls.Add(btn);
}
this.tabControl1.TabPages.Add(tabPage);
}
}
}

 开始码代码,今天分享一个在图纸界面画出折断线的代码

 

public class 图纸工具
{
[MyTeklaCmdAtt(nameof(图纸工具), nameof(折断线), nameof(图纸工具) + "." + nameof(折断线))]
public static void 折断线()
{
DrawingHandler dwgHd = new DrawingHandler();
var doc = dwgHd.GetActiveDrawing();
if (doc == null)
{
return;
}
var p = dwgHd.GetPicker();
p.PickTwoPoints("", "", out Point p1, out Point p2, out ViewBase viewb);
if (p1 == null || p2 == null || viewb == null) return;
if (p1 == p2) return;
var pts = new PointList();
var v = (p2 - p1).GetAsVector().GetNormal();
var dis = p1.DistanceTo(p2);
var p11 = p1.PolarPoint2d(0.05 * dis,v.DegtoXAixs()+180);
pts.Add(p11);
Point p3 = p1.Add(v.MultipleBy(0.4 * dis));
Point p4 = p3.PolarPoint2d(0.08 * dis,v.DegtoXAixs()+50);
Point p6 = p1.Add(v.MultipleBy(0.6 * dis));
Point p5 = p6.PolarPoint2d(0.08 * dis, v.DegtoXAixs()+230);
pts.Add(p3);
pts.Add(p4);
pts.Add(p5);
pts.Add(p6);
var p22 = p2.PolarPoint2d(0.05 * dis, v.DegtoXAixs());
pts.Add(p22);
var pline = new Polyline(viewb, pts);
pline.Insert();
doc.CommitChanges();
}
}
public static class PointEx
{
public static Point GetMidPoint(this Point sp, Point ep)
{
return new Point(0.5 * (ep.X + sp.X),
0.5 * (ep.Y + sp.Y),
0.5 * (ep.Z + sp.Z));
}
public static Point Add(this Point sp, Vector v)
{
return new Point(sp.X + v.X, sp.Y + v.Y + sp.Z + v.Z);
}
public static double DistanceTo(this Point sp, Point ep)
{
return sp.GetVectorTo(ep).GetLength();
}
//public static double Length(this Vector v)
//{
// return v.GetLength();
//}
public static Vector GetAsVector(this Point p)
{
return new Vector(p);
}
public static double DegtoXAixs(this Vector v)
{
if (v.X == 0.0)
{
return v.Y > 0 ? 90 : 270;
}
else if (v.Y == 0.0)
{
return v.X > 0 ? 0 : 180;
}
return Math.Atan(v.Y / v.X) * 180 / Math.PI;
}
public static Vector MultipleBy(this Vector v, double d)
{
return new Vector(v.X * d, v.Y * d, v.Z * d);
}
public static Vector DivideBy(this Vector v, double d)
{
return new Vector(v.X / d, v.Y / d, v.Z / d);
}
public static Vector GetVectorTo(this Point sp, Point ep)
{
return new Vector(ep - sp);
}
public static Point PolarPoint2d(this Point p, double dis, double deg)
{
return new Point(p.X + dis * Math.Cos(deg * Math.PI / 180), p.Y + dis * Math.Sin(deg * Math.PI / 180));
}
}

 

posted @   南胜NanSheng  阅读(366)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示