答案 0 :(得分:0)
我创建了一个继承自标准Windows Forms ComboBox的PopupComboBox类。它有一个Title属性,您可以设置在单击组合时将在弹出窗口中使用的属性。
public class PopupComboBox : ComboBox
{
private string title;
public string Title
{
get { return this.title; }
set { this.title = value; }
}
public PopupComboBox() : base()
{
}
public PopupComboBox (string title)
: base()
{
this.title = title;
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
// Show the popup form
var popup = new SelectItemForm(this.title, this);
var result = popup.ShowDialog(this);
if (result == DialogResult.OK)
{
// Select this item in the ComboBox
SelectedIndex = this.FindStringExact(popup.SelectedDisplay);
}
}
}
当您单击组合时,将出现一个弹出窗体(SelectItemForm下面的源代码)。它使用父PopupComboBox的DataSource,ValueMember和DisplayMember来填充ListView以及组合中的项目列表。当您单击“确定”时,它会将所选项目保存在SelectedValue和SelectedDisplay属性中,以便我们可以在表单关闭时在ComboBox中选择该项目。
public partial class SelectItemForm : Form
{
public object SelectedValue { get; private set; }
public string SelectedDisplay { get; private set; }
public SelectItemForm(string title, PopupComboBox parent)
:base()
{
InitializeComponent();
this.Text = title;
// Add items to the list
foreach (var item in parent.Items)
{
// Get the display and value member properties for this combo box
// and use them for the Code/Name columns in the popup form
var props = item.GetType().GetProperties();
var code = props.Where(p => p.Name == parent.ValueMember).Single().GetValue(item);
var name = props.Where(p => p.Name == parent.DisplayMember).Single().GetValue(item);
listView.Items.Add(new ListViewItem(
new string[] { code.ToString(), name.ToString() }));
}
}
private void btnOk_Click(object sender, EventArgs e)
{
if (listView.SelectedItems != null && listView.SelectedItems.Count > 0)
{
SelectedValue = listView.SelectedItems[0].Text;
SelectedDisplay = listView.SelectedItems[0].SubItems[1].Text;
DialogResult = DialogResult.OK;
}
else
{
MessageBox.Show(this, "Select an item first", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
}
}
以下是表单的设计器部分,您可以在其中查看我为ListView看到的更改的属性:
partial class SelectItemForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.listView = new System.Windows.Forms.ListView();
this.btnOk = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.Code = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.Value = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.SuspendLayout();
//
// listView
//
this.listView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.Code,
this.Value});
this.listView.FullRowSelect = true;
this.listView.GridLines = true;
this.listView.Location = new System.Drawing.Point(3, 3);
this.listView.MultiSelect = false;
this.listView.Name = "listView";
this.listView.Size = new System.Drawing.Size(432, 170);
this.listView.TabIndex = 0;
this.listView.UseCompatibleStateImageBehavior = false;
this.listView.View = System.Windows.Forms.View.Details;
//
// btnOk
//
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOk.Location = new System.Drawing.Point(272, 179);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(75, 23);
this.btnOk.TabIndex = 1;
this.btnOk.Text = "OK";
this.btnOk.UseVisualStyleBackColor = true;
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.Location = new System.Drawing.Point(353, 179);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 2;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// Code
//
this.Code.Text = "Code";
this.Code.Width = 108;
//
// Value
//
this.Value.Text = "Name";
this.Value.Width = 296;
//
// SelectItemForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(440, 214);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOk);
this.Controls.Add(this.listView);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "SelectItemForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Title";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ListView listView;
private System.Windows.Forms.Button btnOk;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.ColumnHeader Code;
private System.Windows.Forms.ColumnHeader Value;
}
我还创建了一个小型测试表单,您可以使用一小部分产品测试PopupComboBox的功能。您需要将PopupComboBox添加到设计器中的表单中,并将其命名为comboPopup。
public partial class TestForm : Form
{
public class Product
{
public string Code { get; set; }
public string Name { get; set; }
}
public TestForm()
{
InitializeComponent();
}
private void TestForm_Load(object sender, EventArgs e)
{
var products = new List<Product>();
products.Add(new Product { Code = "0001", Name = "Coca Cola" });
products.Add(new Product { Code = "0002", Name = "Mountain Dew" });
products.Add(new Product { Code = "0003", Name = "Sprite Zero" });
comboPopup.DataSource = products;
comboPopup.DisplayMember = "Name";
comboPopup.ValueMember = "Code";
}
}