首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 自訂 WinForms 使用者控制項:Label+TextBox 組合元件開發與發佈完整教學

     編輯:關於C#

繼承 UserControl 可將現有控制項封裝為可重複使用的複合元件。本文完整示範建立 LabeledTextBox (標籤+文字方塊) 控制項:定義屬性、設計介面、編譯為 DLL、於客戶端專案參考使用。

1. 控制項原始碼 (LabeledTextBox.cs)

using System;
using System.Windows.Forms;

namespace MyControls
{
    public class LabeledTextBox : UserControl
    {
        private readonly Label _label = new Label();
        private readonly TextBox _textBox = new TextBox();

        public LabeledTextBox()
        {
            // 版面配置
            _label.Location = new Point(0, 0);
            _label.Size = new Size(100, 20);
            _label.AutoSize = false;
            _label.TextAlign = ContentAlignment.MiddleRight;

            _textBox.Location = new Point(105, 0);
            _textBox.Size = new Size(150, 20);
            _textBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;

            Size = new Size(260, 22);
            Controls.Add(_label);
            Controls.Add(_textBox);
        }

        // 覆寫 Text 屬性 -> 繫結至 TextBox
        public override string Text
        {
            get => _textBox.Text;
            set => _textBox.Text = value;
        }

        // 新增 LabelText 屬性 -> 繫結至 Label
        public string LabelText
        {
            get => _label.Text;
            set => _label.Text = value;
        }

        // 選擇性:公開內部 TextBox 以支援事件繫結
        public TextBox InnerTextBox => _textBox;
    }
}

2. 編譯為類別庫 (DLL)

# 命令列編譯 (需參考 System.Windows.Forms.dll)
csc /target:library /r:System.Windows.Forms.dll /r:System.Drawing.dll LabeledTextBox.cs

# 或使用 MSBuild / Visual Studio
# 專案類型:Class Library (.NET Framework / .NET Core / .NET 5+)
# 輸出:MyControls.dll

3. 客戶端專案使用範例 (Program.cs)

using System;
using System.Windows.Forms;
using MyControls; // 參考 MyControls.dll

public class DemoForm : Form
{
    private readonly LabeledTextBox _name = new LabeledTextBox();
    private readonly LabeledTextBox _email = new LabeledTextBox();
    private readonly LabeledTextBox _phone = new LabeledTextBox();
    private readonly Button _btnShow = new Button();

    public DemoForm()
    {
        _name.LabelText = "姓名:";
        _name.Location = new Point(10, 10);

        _email.LabelText = "電子郵件:";
        _email.Location = new Point(10, 40);

        _phone.LabelText = "電話:";
        _phone.Location = new Point(10, 70);

        _btnShow.Text = "顯示數值";
        _btnShow.Location = new Point(10, 100);
        _btnShow.Click += (s, e) =>
        {
            string msg = $"{_name.LabelText}{_name.Text}\n" +
                         $"{_email.LabelText}{_email.Text}\n" +
                         $"{_phone.LabelText}{_phone.Text}";
            MessageBox.Show(msg, "元件屬性值");
        };

        Controls.AddRange(new Control[] { _name, _email, _phone, _btnShow });
        Text = "自訂元件示範";
        ClientSize = new Size(300, 150);
    }

    [STAThread]
    public static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new DemoForm());
    }
}

4. 進階強化:設計階段支援

using System.ComponentModel;
using System.Drawing.Design;

namespace MyControls
{
    [ToolboxItem(true)]
    [DefaultProperty("LabelText")]
    [DefaultEvent("TextChanged")]
    public class LabeledTextBox : UserControl
    {
        // ... 既有程式碼 ...

        [Category("自訂屬性")]
        [Description("標籤顯示文字")]
        [DefaultValue("")]
        public string LabelText { get => _label.Text; set => _label.Text = value; }

        [Category("自訂屬性")]
        [Description("文字方塊內容")]
        [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
        public override string Text { get => _textBox.Text; set => _textBox.Text = value; }

        // 公開 TextBox 事件
        [Browsable(true)]
        [Category("自訂事件")]
        [Description("文字變更時觸發")]
        public event EventHandler TextChanged
        {
            add => _textBox.TextChanged += value;
            remove => _textBox.TextChanged -= value;
        }
    }
}

5. 部署與版本控管建議

  • NuGet 套件:將 MyControls 打包為 .nupkg 發佈至私有/公有 NuGet 伺服器,專案透過 Install-Package MyControls 參考。
  • 強式名稱簽章:啟用 Sign the assembly 避免 DLL Hell。
  • 版本號語意化:Major.Minor.Patch,破壞性變更升 Major。
  • 設計工具組件分離:大型控制項庫建議將設計階段屬性/編輯器獨立為 .Design.dll,避免執行階段載入不必要組件。

常見問題排除

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題原因與解決
工具箱不顯示元件右鍵工具箱 → 選擇項目 → 瀏覽 DLL;或拖曳 DLL 到工具箱
設計階段屬性不顯示確認類別為 public、有 public 無參數建構函式、標記 [ToolboxItem(true)]
執行時找不到 DLL確認 Copy Local = true 或輸出目錄有 DLL;.NET Core 需 PreserveCompilationContext
錨點/版面跑版設定 Anchor、Dock、AutoSize;複雜版面改用 TableLayoutPanel / FlowLayoutPanel