TextBoxをComboBox風に

自作プログラムで、ComboBoxのTestChangeされる仕様が不都合だった。
TextChangeが発生するとテキストボックス内のカーソル位置が先頭にリセットされるという現象。

そこでTextBoxを派生したクラスをComboBox風にしてみた。(少々ダサいが)↓


ソースは以下。

MyTextComboBox:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ABCS.Forms;
using System.Drawing;
using System.Collections;

namespace ABCS.UserClass
{
    class MyTextComboBox : TextBox
    {
        public Form parentForm_ = null;
        private Button btnDown = new Button();
        private frmList frmList_ = null;

        public Form ParentForm
        {
            get
            {
                return this.parentForm_;
            }
            set
            {
                this.parentForm_ = value;
            }

        }

        public System.Windows.Forms.ListBox.ObjectCollection Items
        {
            get
            {
                return this.frmList_.listItems.Items;
            }
        }

        public MyTextComboBox()
            : base() 
        {
            //Form parentForm = this.Container as Form;

            //this.parentForm_ = parentForm;

            this.frmList_ = new frmList(this);

            this.btnDown.Click += this.btnDownOnClick;

//            this.Items.Add("a");
//            this.Items.Add("b");
//            this.Items.Add("c");
        }

        public void setFont()
        {
            this.btnDown.Font = this.Font;
            this.frmList_.listItems.Font = this.Font;
        }

        public void SetDownButton()
        {
            if (this.parentForm_ != null)
            {
                this.parentForm_.Controls.Add(this.btnDown);

                this.btnDown.Top = this.Location.Y;
                this.btnDown.Left = this.Location.X + this.Width;
                this.btnDown.Height = this.Height;
                this.btnDown.Width = 24;


                this.btnDown.Text = "▼";

                this.btnDown.Visible = true;
            }

        }

        protected override void OnLocationChanged(EventArgs e)
        {
            base.OnLocationChanged(e);
            this.SetDownButton();
        }
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            this.SetDownButton();
        }
        protected override void OnFontChanged(EventArgs e)
        {
            base.OnFontChanged(e);
            this.setFont();
        }


        private void btnDownOnClick(object sender, EventArgs e)
        {
            this.frmList_.Visible = true;
            this.frmList_.Top = this.parentForm_.Top + this.Top + this.Height + 32;
            this.frmList_.Left = this.parentForm_.Left + this.Left + 16;
            this.frmList_.Show();
            this.frmList_.TopMost = true;
            System.Windows.Forms.Application.DoEvents();
            this.frmList_.TopMost = false;

        }

    }
}

ここで、デザイン時に、parentFormプロパティを親フォームにセットしてやらないと、「▼」のボタンは出てこない。(下図参照)

ドロップダウンリストは以下のfrmListで実現

frmList.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ABCS.Forms
{
    public partial class frmList : Form
    {
        private TextBox parentTextBox_ = null;

        public frmList(TextBox parentTextBox)
        {
            InitializeComponent();

            this.parentTextBox_ = parentTextBox;
        }

        private void listItems_Click(object sender, EventArgs e)
        {
            if (this.listItems.SelectedItem != null)
            {
                this.parentTextBox_.Text = this.listItems.SelectedItem.ToString();
                this.Hide();
            }
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            this.Hide();
        }
    }
}

frmList.Desiner.cs
(listBoxをpublic にしている)

namespace ABCS.Forms
{
    partial class frmList
    {
        /// 
        /// Required designer variable.
        /// 
        private System.ComponentModel.IContainer components = null;

        /// 
        /// Clean up any resources being used.
        /// 
        /// true if managed resources should be disposed; otherwise, false.
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// 
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// 
        private void InitializeComponent()
        {
            this.listItems = new System.Windows.Forms.ListBox();
            this.SuspendLayout();
            // 
            // listItems
            // 
            this.listItems.Dock = System.Windows.Forms.DockStyle.Fill;
            this.listItems.FormattingEnabled = true;
            this.listItems.ItemHeight = 12;
            this.listItems.Location = new System.Drawing.Point(0, 0);
            this.listItems.Name = "listItems";
            this.listItems.Size = new System.Drawing.Size(284, 262);
            this.listItems.TabIndex = 0;
            this.listItems.Click += new System.EventHandler(this.listItems_Click);
            // 
            // frmList
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 262);
            this.Controls.Add(this.listItems);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.Name = "frmList";
            this.Text = "frmList";
            this.ResumeLayout(false);

        }

        #endregion

        public System.Windows.Forms.ListBox listItems;
    }
}