2010-01-07 76 views
34

Tôi chủ yếu là một nhà phát triển ASP.NET nhưng tôi đang làm việc trên một ứng dụng WinForms và nhận thấy một sự khác biệt lớn giữa combobox ASP.NET (html chọn) và của WinForms. Tôi tìm thấy (có lẽ không chính xác như vậy) rằng combobox của WinForm chỉ có một "nhãn" trong khi ASP.NET cho phép bạn chỉ định một "nhãn" và một "giá trị".Làm thế nào để tạo ra một Combobox Winforms với Label và giá trị?

Tôi đang tìm cách sử dụng combobox WinForms (hoặc một điều khiển so sánh khác) với nhãn và giá trị (Foobar/42329). Điều này có thể không? Tôi đã cố gắng tìm kiếm câu trả lời nhưng chưa đưa ra nhiều. Nếu không có cách nào để thực hiện điều đó, làm thế nào người ta đi trước và thiết kế một combobox WinForm mà sẽ đại diện cho nói thành phố với id cơ sở dữ liệu liên quan của họ?

  • Toronto/2324
  • Montreal/64547
  • Vancouver/1213
+0

Nếu bạn không sử dụng ràng buộc bạn có thể sử dụng này: http://support.microsoft.com/kb/319946, nếu không sử dụng Marcs câu trả lời. –

Trả lời

46

tôi có thể nghĩ ra một vài cách sau:

  • ghi đè các ToString() của một City lớp để return Name + "/" + Id;
  • ditto, nhưng với một TypeConverter
  • thêm một tài sản mà trả lại cùng DisplayText, và sử dụng DisplayMember
  • xây dựng lớp học tạm thời cho dữ liệu

Đối với lần cuối:

var data = cities.Select(city => new { 
    Id = city.Id, Text = city.Name + "/" + city.Id }).ToList(); 
cbo.ValueMember = "Id"; 
cbo.DisplayMember = "Text"; 
cbo.DataSource = data; 
+2

Tôi không biết combobox mạnh đến mức nào ... Tôi đã sử dụng giải pháp này vì tôi cũng là một Linq newb và quyết định đi xuống con đường này. Quy tắc Stackoverflow, cảm ơn các bạn! – nokturnal

+1

Dường như một chút tầm thường, nhưng "Id = city.Id" có thể được đơn giản hóa thành "city.Id" dưới dạng .Net sẽ sử dụng tên của bộ đặt thuộc tính nếu không có chỉ định nào. – Arbiter

+4

@Arbiter yes, tôi biết; Tôi chỉ muốn được rõ ràng ... tránh những bất ngờ khi tôi đổi tên mọi thứ, p –

4

Một ComboBox có thể được ràng buộc với một bộ sưu tập của các đối tượng bằng cách thiết lập tài sản DataSource của nó.

Theo mặc định, thuộc tính SelectedValue sẽ cung cấp cho đối tượng đã được chọn và danh sách sẽ gọi ToString trên mỗi đối tượng và hiển thị kết quả.
Tuy nhiên, nếu bạn đặt thuộc tính DisplayMember của ComboBox, nó sẽ hiển thị giá trị của thuộc tính có tên trong DisplayMember trong danh sách. Tương tự, bạn có thể đặt thuộc tính ValueMember của ComboBox và quyền chọn SelectedValue sẽ trả về giá trị của thuộc tính có tên ValueMember.


Vì vậy, bạn cần phải ràng buộc ComboBox với một danh sách các đối tượng có NameValue tài sản.
Sau đó, bạn có thể đặt thuộc tính [DisplayMember của ComboBox thành NameValueMember thuộc tính là Value.

EDIT: Bạn cũng có thể gọi phương thức Add và cung cấp cho đối tượng như vậy thay vì dữ liệu. Ngoài ra, bạn có thể liên kết nó với một List<T> hoặc một mảng.

+0

Có cách nào để thực hiện điều này mà không cần databinding? Tôi tự thêm các mục vào combobox. – nokturnal

+1

combobox.Items.Add –

+0

Nếu bạn đặt thuộc tính ValueMember/DisplayMember của combobox bạn không cần phải databind. Nó sẽ sử dụng chúng ngay cả khi bạn sử dụng combobox.Add (yourobject); Việc nắm bắt là bạn vẫn cần một đối tượng tên/giá trị. –

6

Bạn có thể thử tạo ra một lớp học nhỏ gọi là ComboBoxItem, như vậy:

public class ComboBoxItem<T> 
{ 
    public string Label { get; set; } 
    public T Value { get; set; } 

    public override string ToString() 
    { 
     return Label ?? string.Empty; 
    } 
} 

Và sau đó khi bạn cần phải nhận được một đối tượng, chỉ cần bỏ nó vào một ComboBoxItem.

+0

Tại sao bạn gọi 'ToString' trên một chuỗi? – SLaks

+2

Anh ấy ghi đè "ToString" để nó không bao giờ rỗng. – EricLaw

1

Có một thuộc tính được gọi là DisplayMember = tên thuộc tính có giá trị sẽ được sử dụng để hiển thị và ValueMember là thuộc tính của giá trị sử dụng.

36

Giả sử rằng các giá trị của bạn là duy nhất, trước tiên bạn có thể điền một từ điển rồi liên kết hộp tổ hợp với từ điển. Thật không may databinding đòi hỏi một IList hoặc một IListSource, do đó bạn phải bọc nó trong Binding Source. Tôi đã tìm thấy giải pháp here.

private void PopulateComboBox() 
    { 
     var dict = new Dictionary<int, string>(); 
     dict.Add(2324, "Toronto"); 
     dict.Add(64547, "Vancouver"); 
     dict.Add(42329, "Foobar"); 

     comboBox1.DataSource = new BindingSource(dict, null); 
     comboBox1.DisplayMember = "Value"; 
     comboBox1.ValueMember = "Key"; 
    } 
+0

Hi làm thế nào để bạn làm điều này trong VB, tôi không có lỗi trong thời gian biên dịch nhưng tôi có lỗi trong thời gian chạy –

+3

DisplayMember và ValueMember cần phải được giao TRƯỚC KHI DataSource được định nghĩa – CJxD

+0

@CJxD Không, không ít nhất nit trong Windows Forms . –

1
 anestezi.DisplayMember = "Text"; 
     anestezi.ValueMember = "Value"; 
     anestezi.DataSource = new[] { 
      new { Text = "Genel", Value = "G" }, 
      new { Text = "Lokal", Value = "L" }, 
      new { Text = "Sedasyon", Value = "S" } 
     }; 
     anestezi.SelectedIndex = 0; 
Các vấn đề liên quan