插件实现:分别通过winform和WPF界面输入操作CAD——CAD c#二次开发

效果如下图所示:

主程序

cs 复制代码
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Windows.Forms;

// 必须添加对 System.Windows.Forms 的引用

namespace IfoxDemo
{
    public class Commands
    {
        [CommandMethod("xx")]
        public void DrawCircles()
        {
            // 获取当前文档和数据库
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            try
            {
                // 创建并显示输入圆信息的窗体
                CircleInputForm form = new CircleInputForm();
                if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    // 获取用户在窗体中输入的半径、数量、颜色、随机分布选项、坐标范围
                    double radius = form.Radius;
                    int count = form.Count;
                    bool isColorRandom = form.IsColorRandom;
                    bool isRandom = form.IsRandom;
                    double xMin = form.XMin;
                    double xMax = form.XMax;
                    double yMin = form.YMin;
                    double yMax = form.YMax;

                    // 开始事务
                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        // 打开块表
                        BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                        // 打开模型空间块表记录
                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                        Random random = new Random();
                        for (int i = 0; i < count; i++)
                        {
                            Autodesk.AutoCAD.Geometry.Point3d center;
                            if (isRandom)
                            {
                                // 如果选择随机分布,生成随机位置
                                double x = random.NextDouble() * (xMax - xMin) + xMin;
                                double y = random.NextDouble() * (yMax - yMin) + yMin;
                                center = new Autodesk.AutoCAD.Geometry.Point3d(x, y, 0);
                            }
                            else
                            {
                                // 否则,使用原点作为圆心
                                center = Autodesk.AutoCAD.Geometry.Point3d.Origin;
                            }

                            // 创建一个圆对象
                            Circle circle = new Circle(center, Autodesk.AutoCAD.Geometry.Vector3d.ZAxis, radius);

                            if (isColorRandom)
                            {
                                // 如果颜色随机,生成随机颜色索引
                                circle.ColorIndex = (short)random.Next(1, 8);
                            }
                            else
                            {
                                // 否则,使用默认颜色索引
                                circle.ColorIndex = form.ColorIndex;
                            }

                            // 将圆添加到模型空间
                            btr.AppendEntity(circle);
                            tr.AddNewlyCreatedDBObject(circle, true);
                        }

                        // 提交事务
                        tr.Commit();
                    }
                    ed.ZoomExtents();
                }
            }
            catch (Exception ex)
            {
                // 输出异常信息到命令行
                ed.WriteMessage("\nError: " + ex.Message);
            }
        }
    }

    
}

窗体文件:

cs 复制代码
using Autodesk.AutoCAD.Windows;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace IfoxDemo
{
    public partial class CircleInputForm : Form
    {
        public double Radius { get; private set; }
        public int Count { get; private set; }
        public short ColorIndex { get; private set; }
        public bool IsRandom { get; private set; }
        public bool IsColorRandom { get; private set; }
        public double XMin { get; private set; }
        public double XMax { get; private set; }
        public double YMin { get; private set; }
        public double YMax { get; private set; }

        private Dictionary<string, short> colorMap = new Dictionary<string, short>
        {
            { "红色", 1 },
            { "黄色", 2 },
            { "绿色", 3 },
            { "青色", 4 },
            { "蓝色", 5 },
            { "洋红色", 6 },
            { "白色", 7 }
        };

        public CircleInputForm()
        {
            InitializeComponent();
            // 初始化颜色选择的 ComboBox
            foreach (var colorName in colorMap.Keys)
            {
                cmbColor.Items.Add(colorName);
            }
            cmbColor.SelectedIndex = 0; // 默认选择红色

            // 设置坐标范围的默认值
            txtXMin.Text = "0";
            txtXMax.Text = "10000";
            txtYMin.Text = "0";
            txtYMax.Text = "10000";
            chkRandom.Checked = true;
            chkColorRandom.Checked = true;
            txtRadius.Text = "100";
            txtCount.Text = "100";
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            double radius;
            int count;
            try
            {
                // 尝试将用户输入的半径和数量转换为相应的数据类型
                if (!double.TryParse(txtRadius.Text, out radius))
                {
                    MessageBox.Show("请输入有效的半径!", "输入错误");
                    txtRadius.Focus();
                    return;
                }

                if (!int.TryParse(txtCount.Text, out count))
                {
                    MessageBox.Show("请输入有效的数量!", "输入错误");
                    txtCount.Focus();
                    return;
                }

                // 若输入都有效,则继续后续处理
                Radius = radius;
                Count = count;
                // 获取用户选择的颜色索引
                ColorIndex = colorMap[cmbColor.SelectedItem.ToString()];
                // 获取是否随机分布的选项
                IsRandom = chkRandom.Checked;
                // 获取颜色是否随机的选项
                IsColorRandom = chkColorRandom.Checked;
                // 获取坐标范围
                XMin = double.Parse(txtXMin.Text);
                XMax = double.Parse(txtXMax.Text);
                YMin = double.Parse(txtYMin.Text);
                YMax = double.Parse(txtYMax.Text);

                // 检查坐标范围的合理性
                if (XMin > XMax || YMin > YMax)
                {
                    MessageBox.Show("坐标范围设置不合理,请确保最小值小于最大值。");
                    return;
                }

                // 关闭窗体并返回 DialogResult.OK
                DialogResult = DialogResult.OK;
                Close();
            }
            catch (Exception ex)
            {
                // 若转换失败,显示错误信息
                MessageBox.Show("输入无效: " + ex.Message);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            // 关闭窗体并返回 DialogResult.Cancel
            DialogResult = DialogResult.Cancel;
            Close();
        }
    }
}

wpf界面如下:

cs 复制代码
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Windows;

namespace IfoxDemo
{
    public partial class MainWindow : Window
    {
        public double Radius { get; private set; }
        public int Count { get; private set; }
        public short ColorIndex { get; private set; }
        public bool IsRandom { get; private set; }
        public bool IsColorRandom { get; private set; }
        public double XMin { get; private set; }
        public double XMax { get; private set; }
        public double YMin { get; private set; }
        public double YMax { get; private set; }

        private Dictionary<string, short> colorMap = new Dictionary<string, short>
        {
            { "红色", 1 },
            { "黄色", 2 },
            { "绿色", 3 },
            { "青色", 4 },
            { "蓝色", 5 },
            { "洋红色", 6 },
            { "白色", 7 }
        };

        public MainWindow()
        {
            InitializeComponent();
            // 默认选择第一个颜色
            cmbColor.SelectedIndex = 0;
        }

        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            double radius;
            int count;

            // 验证半径输入
            if (!double.TryParse(txtRadius.Text, out radius))
            {
                MessageBox.Show("请输入有效的半径!", "输入错误");
                txtRadius.Focus();
                return;
            }

            // 验证数量输入
            if (!int.TryParse(txtCount.Text, out count))
            {
                MessageBox.Show("请输入有效的数量!", "输入错误");
                txtCount.Focus();
                return;
            }

            // 若输入都有效,则继续后续处理
            Radius = radius;
            Count = count;

            // 获取用户选择的颜色索引
            string selectedColor = ((ComboBoxItem)cmbColor.SelectedItem).Content.ToString();
            ColorIndex = colorMap[selectedColor];

            // 获取是否随机分布的选项
            IsRandom = chkRandom.IsChecked.Value;

            // 获取颜色是否随机的选项
            IsColorRandom = chkColorRandom.IsChecked.Value;

            // 定义临时变量用于存储解析结果
            double tempXMin, tempXMax, tempYMin, tempYMax;

            // 获取坐标范围
            if (!double.TryParse(txtXMin.Text, out tempXMin) || !double.TryParse(txtXMax.Text, out tempXMax) ||
                !double.TryParse(txtYMin.Text, out tempYMin) || !double.TryParse(txtYMax.Text, out tempYMax))
            {
                MessageBox.Show("请输入有效的坐标范围!", "输入错误");
                return;
            }

            // 将临时变量的值赋给属性
            XMin = tempXMin;
            XMax = tempXMax;
            YMin = tempYMin;
            YMax = tempYMax;

            // 检查坐标范围的合理性
            if (XMin > XMax || YMin > YMax)
            {
                MessageBox.Show("坐标范围设置不合理,请确保最小值小于最大值。");
                return;
            }

            // 关闭窗体并返回结果
            DialogResult = true;
            Close();
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            // 关闭窗体并返回结果
            DialogResult = false;
            Close();
        }
    }

    public class Commands
    {
        [CommandMethod("xx")]
        public void DrawCircles()
        {
            // 获取当前文档和数据库
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            try
            {
                // 创建并显示输入圆信息的窗体
                MainWindow form = new MainWindow();
                if (form.ShowDialog() == true)
                {
                    // 获取用户在窗体中输入的半径、数量、颜色、随机分布选项、坐标范围
                    double radius = form.Radius;
                    int count = form.Count;
                    bool isColorRandom = form.IsColorRandom;
                    bool isRandom = form.IsRandom;
                    double xMin = form.XMin;
                    double xMax = form.XMax;
                    double yMin = form.YMin;
                    double yMax = form.YMax;

                    // 开始事务
                    using (Transaction tr = db.TransactionManager.StartTransaction())
                    {
                        // 打开块表
                        BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                        // 打开模型空间块表记录
                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                        Random random = new Random();
                        for (int i = 0; i < count; i++)
                        {
                            Point3d center;
                            if (isRandom)
                            {
                                // 如果选择随机分布,生成随机位置
                                double x = random.NextDouble() * (xMax - xMin) + xMin;
                                double y = random.NextDouble() * (yMax - yMin) + yMin;
                                center = new Point3d(x, y, 0);
                            }
                            else
                            {
                                // 否则,使用原点作为圆心
                                center = Point3d.Origin;
                            }

                            // 创建一个圆对象
                            Circle circle = new Circle(center, Vector3d.ZAxis, radius);

                            if (isColorRandom)
                            {
                                // 如果颜色随机,生成随机颜色索引
                                circle.ColorIndex = (short)random.Next(1, 8);
                            }
                            else
                            {
                                // 否则,使用默认颜色索引
                                circle.ColorIndex = form.ColorIndex;
                            }

                            // 将圆添加到模型空间
                            btr.AppendEntity(circle);
                            tr.AddNewlyCreatedDBObject(circle, true);
                        }

                        // 提交事务
                        tr.Commit();
                    }
                    ed.ZoomExtents();
                }
            }
            catch (Exception ex)
            {
                // 输出异常信息到命令行
                ed.WriteMessage("\nError: " + ex.Message);
            }
        }
    }
}
cs 复制代码
<Window x:Class="IfoxDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="输入圆信息" Height="350" Width="300">
    <Grid>
        <!-- 半径输入 -->
        <Label Content="半径:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="txtRadius" HorizontalAlignment="Left" Height="23" Margin="60,10,0,0" TextWrapping="Wrap" Text="100" VerticalAlignment="Top" Width="120"/>

        <!-- 数量输入 -->
        <Label Content="数量:" HorizontalAlignment="Left" Margin="10,40,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="txtCount" HorizontalAlignment="Left" Height="23" Margin="60,40,0,0" TextWrapping="Wrap" Text="100" VerticalAlignment="Top" Width="120"/>

        <!-- 颜色选择 -->
        <Label Content="颜色:" HorizontalAlignment="Left" Margin="10,70,0,0" VerticalAlignment="Top"/>
        <ComboBox x:Name="cmbColor" HorizontalAlignment="Left" Margin="60,70,0,0" VerticalAlignment="Top" Width="120">
            <ComboBoxItem Content="红色"/>
            <ComboBoxItem Content="黄色"/>
            <ComboBoxItem Content="绿色"/>
            <ComboBoxItem Content="青色"/>
            <ComboBoxItem Content="蓝色"/>
            <ComboBoxItem Content="洋红色"/>
            <ComboBoxItem Content="白色"/>
        </ComboBox>

        <!-- 随机分布圆位置复选框 -->
        <CheckBox x:Name="chkRandom" Content="随机分布圆位置" HorizontalAlignment="Left" Margin="10,100,0,0" VerticalAlignment="Top" IsChecked="True"/>

        <!-- 颜色随机分布复选框 -->
        <CheckBox x:Name="chkColorRandom" Content="颜色随机分布" HorizontalAlignment="Left" Margin="10,130,0,0" VerticalAlignment="Top" IsChecked="True"/>

        <!-- X 坐标范围 -->
        <Label Content="X 坐标范围:" HorizontalAlignment="Left" Margin="10,160,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="txtXMin" HorizontalAlignment="Left" Height="23" Margin="100,160,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="50"/>
        <Label Content="-" HorizontalAlignment="Left" Margin="147,158,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="txtXMax" HorizontalAlignment="Left" Height="23" Margin="160,160,0,0" TextWrapping="Wrap" Text="10000" VerticalAlignment="Top" Width="50"/>

        <!-- Y 坐标范围 -->
        <Label Content="Y 坐标范围:" HorizontalAlignment="Left" Margin="10,190,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="txtYMin" HorizontalAlignment="Left" Height="23" Margin="100,190,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="50"/>
        <Label Content="-" HorizontalAlignment="Left" Margin="147,188,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="txtYMax" HorizontalAlignment="Left" Height="23" Margin="160,190,0,0" TextWrapping="Wrap" Text="10000" VerticalAlignment="Top" Width="50"/>

        <!-- 确定按钮 -->
        <Button Content="确定" HorizontalAlignment="Left" Margin="50,230,0,0" VerticalAlignment="Top" Width="75" Click="btnOK_Click"/>

        <!-- 取消按钮 -->
        <Button Content="取消" HorizontalAlignment="Left" Margin="150,230,0,0" VerticalAlignment="Top" Width="75" Click="btnCancel_Click"/>
        <!-- 版权信息 -->
        <TextBlock Text="版权#山水(qq443440204)" 
                   HorizontalAlignment="Center" 
                   VerticalAlignment="Bottom" 
                   Margin="0,0,0,10" 
                   Foreground="Red" 
                   FontWeight="Bold"/>
    </Grid>
</Window>

当前结构问题 :随着功能的增加,代码可能会变得臃肿,难以管理。

优化建议:可以将相关的功能进行模块化拆分,例如将与圆的绘制逻辑相关的代码提取到一个独立的类中,将与坐标范围处理相关的代码提取到另一个类中。这样可以提高代码的可读性和可维护性。
MVVM 模式的应用

优势:

分离关注点:MVVM 模式将应用程序分为三个主要部分,即模型(Model)、视图(View)和视图模型(ViewModel)。模型负责处理数据和业务逻辑,视图负责展示用户界面,视图模型作为中间桥梁,连接模型和视图,负责处理视图的交互和数据绑定。这样可以使代码的各个部分职责更加明确,便于开发、测试和维护。

提高可测试性:由于视图模型不依赖于具体的视图,因此可以更容易地对其进行单元测试。可以通过模拟视图模型的依赖项来测试其业务逻辑,而无需依赖于 UI 界面。

数据绑定和交互:MVVM 模式利用数据绑定技术,使得视图和视图模型之间的数据交互更加便捷和直观。当视图模型中的数据发生变化时,视图会自动更新;反之,当用户在视图中进行操作时,也会自动更新视图模型中的数据。

通用功能使用wpf实现:

相关推荐
Source.Liu5 小时前
【学Rust写CAD】26 图形像素获取(pixel_fetch.rs)
rust·cad
Source.Liu2 天前
【学Rust写CAD】20 平铺模式结构体(spread.rs)
rust·cad
Source.Liu3 天前
【学Rust写CAD】19 颜色渐变定义(gradient_stop.rs)
rust·cad
Source.Liu4 天前
【学Rust写CAD】15 定点数实现(fixed.rs)
rust·cad
Source.Liu4 天前
【学Rust写CAD】18 定点数2D仿射变换矩阵结构体(MatrixFixedPoint结构别名)
矩阵·rust·cad
Source.Liu5 天前
【学Rust写CAD】13 图像结构体(Image.rs)
rust·cad
Source.Liu5 天前
【学Rust写CAD】16 零标记类型(zero.rs)
rust·cad
Source.Liu7 天前
【学Rust写CAD】14线性插值函数(加入color.rs)
rust·cad
cuicuiniu5219 天前
如何通过CAD坐标找点?
cad·cad看图·cad看图软件