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; } }