共享项目中使用Wpf和Winform——c# CAD二次开发

在共享项目中手动编码创建 UI(如通过代码逐个初始化控件)的优缺点可简单汇总如下:

优点:

  • 代码可控性强:直接操作控件属性和布局,避免设计器生成的冗余代码,便于理解和调试。
  • 灵活性高:适合复杂交互逻辑或动态布局,可在运行时灵活调整 UI 元素。
  • 跨平台适配性好:若项目涉及跨平台(如通过代码适配不同框架),手动编码更易统一逻辑。

缺点:

  • 开发效率低:需手动编写大量控件初始化代码,比可视化设计器耗时更多。
  • 维护成本高:UI 变更时需修改多处代码,易因疏忽导致错误(如控件位置、事件绑定)。
  • 可视化预览困难:无法通过设计器实时查看布局效果,需运行程序才能验证。
  • 团队协作易冲突:多人修改同一 UI 代码时,易因布局逻辑重叠导致合并冲突。

项目结构如下:

wpf类:

cs 复制代码
using System.Windows.Controls;
using System.Windows;
using Button = System.Windows.Controls.Button;
using TextBox = System.Windows.Controls.TextBox;
using UserControl = System.Windows.Controls.UserControl;
using MessageBox = System.Windows.MessageBox;
using Window = System.Windows.Window;

namespace CadShared
{
    // WPF窗口包装类 - 用于在AutoCAD中显示WPF用户控件
    public class UWpf : Window, IDisposable
    {
        private bool disposed = false;
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    userControl.OkClicked -= UserControl_OkClicked;
                    userControl.CancelClicked -= UserControl_CancelClicked;
                    userControl = null;
                }
                disposed = true;
            }
        }
        ~UWpf() { Dispose(false); }
        private WpfUserControl userControl;

        public  void Show()
        {
            // 直接创建和显示窗体,不使用using语句
            var window = new UWpf();
            bool? result = window.ShowDialog();

            // 处理窗体返回结果
            if (result == true)
            {
                Document doc = Acap.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                ed.WriteMessage("\n输入1: " + window.Input1);
                ed.WriteMessage("\n输入2: " + window.Input2);
            }
            // 不需要手动调用Dispose,因为Window不实现IDisposable
        }
        // 窗体属性,用于获取用户输入
        public string Input1
        {
            get { return userControl.Input1; }
            set { userControl.Input1 = value; }
        }

        public string Input2
        {
            get { return userControl.Input2; }
            set { userControl.Input2 = value; }
        }

        public UWpf()
        {
            // 设置窗口基本属性
            this.Title = "Wpf数据输入";
            this.Width = 300;
            this.Height = 200;
            this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            this.ResizeMode = ResizeMode.NoResize;

            // 创建用户控件
            userControl = new WpfUserControl();

            // 设置内容
            this.Content = userControl;

            // 注册事件
            userControl.OkClicked += UserControl_OkClicked;
            userControl.CancelClicked += UserControl_CancelClicked;
        }

        // 处理确定按钮点击事件
        private void UserControl_OkClicked(object sender, EventArgs e)
        {
            // 验证输入
            if (string.IsNullOrEmpty(Input1))
            {
                MessageBox.Show("请输入第一个值!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (string.IsNullOrEmpty(Input2))
            {
                MessageBox.Show("请输入第二个值!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            // 设置对话框结果为True并关闭窗口
            this.DialogResult = true;
            this.Close();
        }

        // 处理取消按钮点击事件
        private void UserControl_CancelClicked(object sender, EventArgs e)
        {
            // 设置对话框结果为False并关闭窗口
            this.DialogResult = false;
            this.Close();
        }
    }

    // WPF用户控件 - 包含两个文本框和两个按钮
    public class WpfUserControl : UserControl
    {
        private TextBox txtInput1;
        private TextBox txtInput2;
        private Button btnOk;
        private Button btnCancel;

        // 事件声明
        public event EventHandler OkClicked;
        public event EventHandler CancelClicked;

        // 控件属性
        public string Input1
        {
            get { return txtInput1.Text; }
            set { txtInput1.Text = value; }
        }

        public string Input2
        {
            get { return txtInput2.Text; }
            set { txtInput2.Text = value; }
        }

        public WpfUserControl()
        {
            // 创建网格布局
            Grid grid = new Grid();
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

            // 创建文本框1
            txtInput1 = new TextBox();
            txtInput1.Margin = new Thickness(10);
            Grid.SetRow(txtInput1, 0);
            Grid.SetColumnSpan(txtInput1, 2);

            // 创建文本框2
            txtInput2 = new TextBox();
            txtInput2.Margin = new Thickness(10);
            Grid.SetRow(txtInput2, 1);
            Grid.SetColumnSpan(txtInput2, 2);

            // 创建确定按钮
            btnOk = new Button();
            btnOk.Content = "确定";
            btnOk.Margin = new Thickness(10);
            btnOk.Click += BtnOk_Click;
            Grid.SetRow(btnOk, 2);
            Grid.SetColumn(btnOk, 0);

            // 创建取消按钮
            btnCancel = new Button();
            btnCancel.Content = "取消";
            btnCancel.Margin = new Thickness(10);
            btnCancel.Click += BtnCancel_Click;
            Grid.SetRow(btnCancel, 2);
            Grid.SetColumn(btnCancel, 1);

            // 添加控件到网格
            grid.Children.Add(txtInput1);
            grid.Children.Add(txtInput2);
            grid.Children.Add(btnOk);
            grid.Children.Add(btnCancel);

            // 设置用户控件内容
            this.Content = grid;
        }

        // 确定按钮点击事件
        private void BtnOk_Click(object sender, RoutedEventArgs e)
        {
            // 触发OkClicked事件
            OkClicked?.Invoke(this, EventArgs.Empty);
        }

        // 取消按钮点击事件
        private void BtnCancel_Click(object sender, RoutedEventArgs e)
        {
            // 触发CancelClicked事件
            CancelClicked?.Invoke(this, EventArgs.Empty);
        }
    }
}

下面无dispose

cs 复制代码
using System.Windows.Controls;
using System.Windows;
using Button = System.Windows.Controls.Button;
using TextBox = System.Windows.Controls.TextBox;
using UserControl = System.Windows.Controls.UserControl;
using MessageBox = System.Windows.MessageBox;
using Window = System.Windows.Window;

namespace CadShared
{
    public class UWpfClass
    {
    }
    // WPF窗口包装类 - 用于在AutoCAD中显示WPF用户控件
    public class UWpf : Window
    {
        private WpfUserControl userControl;

        public  void Show()
        {
            // 直接创建和显示窗体,不使用using语句
            var window = new UWpf();
            bool? result = window.ShowDialog();

            // 处理窗体返回结果
            if (result == true)
            {
                Document doc = Acap.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                ed.WriteMessage("\n输入1: " + window.Input1);
                ed.WriteMessage("\n输入2: " + window.Input2);
            }
            // 不需要手动调用Dispose,因为Window不实现IDisposable
        }
        // 窗体属性,用于获取用户输入
        public string Input1
        {
            get { return userControl.Input1; }
            set { userControl.Input1 = value; }
        }

        public string Input2
        {
            get { return userControl.Input2; }
            set { userControl.Input2 = value; }
        }

        public UWpf()
        {
            // 设置窗口基本属性
            this.Title = "Wpf数据输入";
            this.Width = 300;
            this.Height = 200;
            this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            this.ResizeMode = ResizeMode.NoResize;

            // 创建用户控件
            userControl = new WpfUserControl();

            // 设置内容
            this.Content = userControl;

            // 注册事件
            userControl.OkClicked += UserControl_OkClicked;
            userControl.CancelClicked += UserControl_CancelClicked;
        }

        // 处理确定按钮点击事件
        private void UserControl_OkClicked(object sender, EventArgs e)
        {
            // 验证输入
            if (string.IsNullOrEmpty(Input1))
            {
                MessageBox.Show("请输入第一个值!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (string.IsNullOrEmpty(Input2))
            {
                MessageBox.Show("请输入第二个值!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            // 设置对话框结果为True并关闭窗口
            this.DialogResult = true;
            this.Close();
        }

        // 处理取消按钮点击事件
        private void UserControl_CancelClicked(object sender, EventArgs e)
        {
            // 设置对话框结果为False并关闭窗口
            this.DialogResult = false;
            this.Close();
        }
    }

    // WPF用户控件 - 包含两个文本框和两个按钮
    public class WpfUserControl : UserControl
    {
        private TextBox txtInput1;
        private TextBox txtInput2;
        private Button btnOk;
        private Button btnCancel;

        // 事件声明
        public event EventHandler OkClicked;
        public event EventHandler CancelClicked;

        // 控件属性
        public string Input1
        {
            get { return txtInput1.Text; }
            set { txtInput1.Text = value; }
        }

        public string Input2
        {
            get { return txtInput2.Text; }
            set { txtInput2.Text = value; }
        }

        public WpfUserControl()
        {
            // 创建网格布局
            Grid grid = new Grid();
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

            // 创建文本框1
            txtInput1 = new TextBox();
            txtInput1.Margin = new Thickness(10);
            Grid.SetRow(txtInput1, 0);
            Grid.SetColumnSpan(txtInput1, 2);

            // 创建文本框2
            txtInput2 = new TextBox();
            txtInput2.Margin = new Thickness(10);
            Grid.SetRow(txtInput2, 1);
            Grid.SetColumnSpan(txtInput2, 2);

            // 创建确定按钮
            btnOk = new Button();
            btnOk.Content = "确定";
            btnOk.Margin = new Thickness(10);
            btnOk.Click += BtnOk_Click;
            Grid.SetRow(btnOk, 2);
            Grid.SetColumn(btnOk, 0);

            // 创建取消按钮
            btnCancel = new Button();
            btnCancel.Content = "取消";
            btnCancel.Margin = new Thickness(10);
            btnCancel.Click += BtnCancel_Click;
            Grid.SetRow(btnCancel, 2);
            Grid.SetColumn(btnCancel, 1);

            // 添加控件到网格
            grid.Children.Add(txtInput1);
            grid.Children.Add(txtInput2);
            grid.Children.Add(btnOk);
            grid.Children.Add(btnCancel);

            // 设置用户控件内容
            this.Content = grid;
        }

        // 确定按钮点击事件
        private void BtnOk_Click(object sender, RoutedEventArgs e)
        {
            // 触发OkClicked事件
            OkClicked?.Invoke(this, EventArgs.Empty);
        }

        // 取消按钮点击事件
        private void BtnCancel_Click(object sender, RoutedEventArgs e)
        {
            // 触发CancelClicked事件
            CancelClicked?.Invoke(this, EventArgs.Empty);
        }
    }
}

窗体winform:

cs 复制代码
using System.Drawing;
namespace CadShared
{
    public static class Class1
    {
        [CommandMethod("xx")]
        public static void ShowWPF()
        {
            // 直接创建和显示窗体,不使用using语句
            var window = new UWpf();
            bool? result = window.ShowDialog();
            // 处理窗体返回结果
            if (result == true)
            {
                Document doc = Acap.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                ed.WriteMessage("\n输入1: " + window.Input1);
                ed.WriteMessage("\n输入2: " + window.Input2);
            }
            // 不需要手动调用Dispose,因为Window不实现IDisposable
        }
        public static void UFormDemo()
        {
            // 创建并显示自定义窗体
            using (var form = new UForm())
            {
                // 获取当前文档和数据库
                Document doc =Acap.DocumentManager.MdiActiveDocument;

                // 在UI线程上显示窗体
#if net48
                Acap.DocumentManager.MdiActiveDocument.Window.Focus();
#endif
                DialogResult result = form.ShowDialog();

                // 处理窗体返回结果
                if (result == DialogResult.OK)
                {
                    // 输出用户输入到AutoCAD命令行
                    doc.Editor.WriteMessage("\n输入1: " + form.Input1);
                    doc.Editor.WriteMessage("\n输入2: " + form.Input2);
                }
            }
        }
        public static void 弹窗Demo()
        {
            // This is a placeholder command that does nothing.
            // You can replace this with your actual command logic.
            MessageBox.Show("Hello from CadShared!");
        }
    }
    // 自定义窗体类 - 手动创建所有UI元素
    public class UForm : Form, IDisposable
    {
        private TextBox txtInput1;
        private TextBox txtInput2;
        private Button btnOk;
        private Button btnCancel;

        // 窗体属性,用于获取用户输入
        public string Input1
        {
            get { return txtInput1.Text; }
            set { txtInput1.Text = value; }
        }

        public string Input2
        {
            get { return txtInput2.Text; }
            set { txtInput2.Text = value; }
        }

        // 窗体构造函数
        public UForm()
        {
            // 设置窗体基本属性
            this.Text = "数据输入";
            this.Size = new Size(300, 200);
            this.StartPosition = FormStartPosition.CenterScreen;

            // 初始化控件
            InitializeComponents();
        }

        // 手动初始化所有控件
        private void InitializeComponents()
        {
            // 创建文本框1
            txtInput1 = new TextBox();
            txtInput1.Location = new Point(20, 30);
            txtInput1.Size = new Size(240, 20);

            // 创建文本框2
            txtInput2 = new TextBox();
            txtInput2.Location = new Point(20, 70);
            txtInput2.Size = new Size(240, 20);

            // 创建确定按钮
            btnOk = new Button();
            btnOk.Text = "确定";
            btnOk.Location = new Point(50, 120);
            btnOk.Size = new Size(80, 30);
            btnOk.Click += BtnOk_Click;

            // 创建取消按钮
            btnCancel = new Button();
            btnCancel.Text = "取消";
            btnCancel.Location = new Point(160, 120);
            btnCancel.Size = new Size(80, 30);
            btnCancel.Click += BtnCancel_Click;

            // 将控件添加到窗体
            this.Controls.Add(txtInput1);
            this.Controls.Add(txtInput2);
            this.Controls.Add(btnOk);
            this.Controls.Add(btnCancel);
        }

        // 确定按钮点击事件处理
        private void BtnOk_Click(object sender, EventArgs e)
        {
            // 验证输入
            if (string.IsNullOrEmpty(txtInput1.Text))
            {
                MessageBox.Show("请输入第一个值!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (string.IsNullOrEmpty(txtInput2.Text))
            {
                MessageBox.Show("请输入第二个值!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 设置对话框结果为OK并关闭窗体
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        // 取消按钮点击事件处理
        private void BtnCancel_Click(object sender, EventArgs e)
        {
            // 设置对话框结果为Cancel并关闭窗体
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }


        // 资源释放相关成员
        private bool _disposed = false;

        // 实现IDisposable.Dispose方法
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        // 受保护的Dispose方法,支持显式和隐式释放
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // 释放托管资源
                    // 例如:释放自定义的托管对象
                }

                // 释放非托管资源
                // 例如:关闭文件句柄、释放API句柄等

                _disposed = true;
            }
        }

        // 析构函数,作为资源释放的后备机制
        ~UForm()
        {
            Dispose(false);
        }
    }
}

下面无 dispose:

cs 复制代码
using System.Drawing;
namespace CadShared
{
    public static class Class1
    {
        [CommandMethod("xx")]
        public static void ShowWPF()
        {
            // 直接创建和显示窗体,不使用using语句
            var window = new UWpf();
            bool? result = window.ShowDialog();
            // 处理窗体返回结果
            if (result == true)
            {
                Document doc = Acap.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                ed.WriteMessage("\n输入1: " + window.Input1);
                ed.WriteMessage("\n输入2: " + window.Input2);
            }
            // 不需要手动调用Dispose,因为Window不实现IDisposable
        }
        public static void UFormDemo()
        {
            // 创建并显示自定义窗体
            using (var form = new UForm())
            {
                // 获取当前文档和数据库
                Document doc =Acap.DocumentManager.MdiActiveDocument;

                // 在UI线程上显示窗体
#if net48
                Acap.DocumentManager.MdiActiveDocument.Window.Focus();
#endif
                DialogResult result = form.ShowDialog();

                // 处理窗体返回结果
                if (result == DialogResult.OK)
                {
                    // 输出用户输入到AutoCAD命令行
                    doc.Editor.WriteMessage("\n输入1: " + form.Input1);
                    doc.Editor.WriteMessage("\n输入2: " + form.Input2);
                }
            }
        }
        public static void 弹窗Demo()
        {
            // This is a placeholder command that does nothing.
            // You can replace this with your actual command logic.
            MessageBox.Show("Hello from CadShared!");
        }
    }
    // 自定义窗体类 - 手动创建所有UI元素
    public class UForm : Form
    {
        private TextBox txtInput1;
        private TextBox txtInput2;
        private Button btnOk;
        private Button btnCancel;

        // 窗体属性,用于获取用户输入
        public string Input1
        {
            get { return txtInput1.Text; }
            set { txtInput1.Text = value; }
        }

        public string Input2
        {
            get { return txtInput2.Text; }
            set { txtInput2.Text = value; }
        }

        // 窗体构造函数
        public UForm()
        {
            // 设置窗体基本属性
            this.Text = "数据输入";
            this.Size = new Size(300, 200);
            this.StartPosition = FormStartPosition.CenterScreen;

            // 初始化控件
            InitializeComponents();
        }

        // 手动初始化所有控件
        private void InitializeComponents()
        {
            // 创建文本框1
            txtInput1 = new TextBox();
            txtInput1.Location = new Point(20, 30);
            txtInput1.Size = new Size(240, 20);

            // 创建文本框2
            txtInput2 = new TextBox();
            txtInput2.Location = new Point(20, 70);
            txtInput2.Size = new Size(240, 20);

            // 创建确定按钮
            btnOk = new Button();
            btnOk.Text = "确定";
            btnOk.Location = new Point(50, 120);
            btnOk.Size = new Size(80, 30);
            btnOk.Click += BtnOk_Click;

            // 创建取消按钮
            btnCancel = new Button();
            btnCancel.Text = "取消";
            btnCancel.Location = new Point(160, 120);
            btnCancel.Size = new Size(80, 30);
            btnCancel.Click += BtnCancel_Click;

            // 将控件添加到窗体
            this.Controls.Add(txtInput1);
            this.Controls.Add(txtInput2);
            this.Controls.Add(btnOk);
            this.Controls.Add(btnCancel);
        }

        // 确定按钮点击事件处理
        private void BtnOk_Click(object sender, EventArgs e)
        {
            // 验证输入
            if (string.IsNullOrEmpty(txtInput1.Text))
            {
                MessageBox.Show("请输入第一个值!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (string.IsNullOrEmpty(txtInput2.Text))
            {
                MessageBox.Show("请输入第二个值!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 设置对话框结果为OK并关闭窗体
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        // 取消按钮点击事件处理
        private void BtnCancel_Click(object sender, EventArgs e)
        {
            // 设置对话框结果为Cancel并关闭窗体
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }
    }
}
相关推荐
大腾智能9 天前
点击启动「高效模式」:大腾智能 CAD 重构研发设计生产力
cad·工业软件·工业数字化·工业设计协同
cuicuiniu52123 天前
CAD如何导出PDF?PDF如何转CAD?详细教程来了
cad·cad格式转换·cad看图·cad看图软件
城市数据匠1 个月前
31【干货】Arcgis属性表常用查询表达式实战大全
arcgis·gis·cad·国土空间规划·自然资源局
飞翼剑仆2 个月前
OCC中的参数方程简介
cad
Source.Liu2 个月前
【Raqote】 1.2 路径填充ShaderClipMaskBlitter结构体(blitter.rs)
rust·cad
Source.Liu2 个月前
【学Rust写CAD】35 alpha_mul_256(alpha256.rs补充方法)
rust·cad
Source.Liu2 个月前
【学Rust写CAD】30 Alpha256结构体补充方法(alpha256.rs)
rust·cad
Source.Liu2 个月前
【学Rust写CAD】23 渐变效果(gradient_source.rs)
rust·cad
Source.Liu2 个月前
【学Rust写CAD】27 双线性插值函数(bilinear_interpolation.rs)
后端·rust·cad