2008-11-19 49 views
30

Tôi có quyền nghĩ rằng không có cách nào để đặt giá trị đã chọn trong danh sách Select Class C# sau khi nó được tạo không? Đó có phải là một chút ngớ ngẩn?Đặt giá trị đã chọn trong SelectList sau khi instantiation

+1

Tôi phải đồng ý với bạn về việc đó là ngớ ngẩn. Các SelectList dường như đã được cố ý "nerfed" để buộc bạn tạo ra các mô hình xem tinh khiết hơn (và nặng). Một trường hợp cụ thể của điều này là nếu bạn muốn sử dụng lại danh sách lựa chọn trong một bảng trong đó mỗi hàng sẽ căn cứ giá trị đã chọn của nó khỏi một danh sách khác trong mô hình khung nhìn của bạn. Nếu bạn muốn sử dụng SelectList, bạn thực sự phải tạo một mảng SelectList được gán sẵn với giá trị đã chọn vì không có cách nào để chọn nó "ngay lập tức" trước khi bạn sử dụng nó trong mã xem dao cạo cho hàng cụ thể đó. – Johncl

Trả lời

18

Tôi nghĩ rằng bạn đang chiến đấu trong khuôn khổ. Các dữ liệu đi vào quan điểm của bạn nên được tạo ra ở phút cuối cùng có thể (LPM).

Suy nghĩ theo cách này, một SelectList là loại để cấp nguồn trợ giúp HTML DropDownList. Nó KHÔNG phải là nơi để lưu trữ dữ liệu trong khi bạn quyết định cách xử lý nó.

Giải pháp tốt hơn là truy xuất dữ liệu của bạn thành List<T> và sau đó khởi tạo SelectList khi bạn cần.Một lợi ích trực tiếp của thực tế này là nó cho phép bạn sử dụng lại List<T> bạn để biết thêm hơn một DropDownList, chẳng hạn như:

Country of birth 
Country of residence 

Những SelectLists tất cả sử dụng danh sách quốc gia cần loại List<Country>.

Bạn có thể sử dụng của bạn List<T> tại 'last minute' như trong ví dụ này:

public class TaxCheatsFormViewModel 
{ 
    private List<Country> countries { get; set; } 

    public TaxCheat Cheat { get; private set; } 
    public SelectList CountryOfBirth { get; private set; } 
    public SelectList CountryOfResidence { get; private set; } 
    public SelectList CountryOfDomicile { get; private set; } 

    public TaxCheatsFormViewModel(TaxCheat baddie) 
    { 
     TaxCheat = baddie; 
     countries = TaxCheatRepository.GetList<Country>(); 
     CountryOfBirth = new SelectList(countries, baddie.COB); 
     CountryOfResidence = new SelectList(countries, baddie.COR); 
     CountryOfDomicile = new SelectList(countries, baddie.COD); 
    } 
} 

Điểm phúc mà bạn nên lưu dữ liệu của bạn trong một List<T> cho đến khi bạn thực sự cần phải đầu ra nó; phút cuối cùng có thể (LPM).

+0

Đây thực sự là cách tôi đã đi. Theo quan điểm của tôi, tôi tạo một SelectList từ danh sách của mình. Nếu có thể, tôi có một phương thức trợ giúp thực hiện điều này. –

0

Bạn có nghĩa là phía máy khách, trong trình duyệt?

var select = document.getElementById('mySelect'); 
select.options[newIndex].selected = true; 
3

Thuộc tính "SelectedValue" là chỉ đọc. Đặt nó trong constructor là cách duy nhất.

Tor, SelectList là cấu trúc ASP.NET MVC được sử dụng để tạo danh sách thả xuống. Làm theo cách của bạn cũng nên làm việc, nhưng SelectList sẽ làm điều đó cho bạn (và không phải trong JS) nếu được thực hiện đúng cách.

+8

Tại sao, vì tình yêu của thần, nó là chỉ đọc? Và tại sao bạn không thể thao tác các mục sau khi tạo bản sao? Và tại sao sau đó nó có thể không được tiếp xúc như một mảng chỉ đọc? Kiểu dữ liệu này vượt xa tôi! –

+0

Nếu bạn không thích, hãy viết phiên bản của riêng bạn. Nó không phức tạp, chàng trai. – Will

+15

@ will: True, nhưng tôi không nghĩ rằng tôi là người duy nhất có những cảm xúc này đối với lớp SelectList. Tất cả chúng ta có thể tự viết không? –

1

Tôi nghĩ bạn có thể làm điều này trong bộ điều khiển. Nếu bạn định hiển thị danh sách thả xuống với tên/ID StateCode, thì bạn có thể đặt trạng thái đã chọn bằng cách sử dụng mã sau khi SelectList được tạo:

ViewData ["StateCode"] = "VT";

Dường như danh sách thả xuống HTML helper tìm kiếm một mục ViewData có cùng tên với danh sách thả xuống đang được tạo.

Tôi không nghĩ mình thích sử dụng kỹ thuật này, nhưng có vẻ như nó hoạt động.

Tôi đồng ý rằng lớp SelectList hơi yếu vào lúc này. Tôi muốn có thể tạo một SelectList và sau đó chọn một giá trị sau đó bằng giá trị hoặc văn bản.

+0

Tôi nhận thấy rằng nó bắt đầu làm cho sence khi bạn sử dụng một bộ sưu tập thường xuyên trong bộ điều khiển và chọn danh sách chỉ ở phút cuối cùng trong xem. Mặc dù tôi không thực sự thích nó theo cách đó, nó lấy đi rất nhiều ma sát ... –

0

Đối tượng SelectList chỉ đọc sau khi được tạo. nếu bạn muốn chọn một cái gì đó bạn làm tốt hơn nó thích:

<%= Html.DropDownList("clientId", ViewData["clients"] as List<SelectListItem>,)%> 

Và trong các mã sau:

ViewData["clientId"] = "ASD"; //This should be the value of item you want to select 
    ViewData["clients"] = clientItemList; //List<SelectListItem> 
+0

Tôi cố gắng tránh xa mã đằng sau vì điều này sẽ phân phối mã giữa bộ điều khiển, chế độ xem của tôi và mã của tôi phía sau. Điều tôi làm bây giờ là khởi tạo SelectListItem trong giao diện. Không phải như thế nào tôi thích nó, nhưng đó chỉ là cách cookie sụp đổ. –

0

thể làm điều đó khá dễ dàng với jQuery;

$(function() { 
    $("#myselectlist option[@value='ItemToSelectValue'].attr('selected', 'true'); 
}); 
+0

Câu hỏi đặt ra là nói về loại SelectList kiểu C#. Tôi sẽ cập nhật OP để loại bỏ sự nhầm lẫn. –

0

Tôi cần một danh sách thả xuống trong lưới có thể chỉnh sửa với giá trị thả xuống được chọn trước. Ngoài ra, dữ liệu danh sách lựa chọn được cung cấp bởi bộ điều khiển cho chế độ xem, vì vậy dữ liệu được tạo trước khi chế độ xem sử dụng nó. Khi khung nhìn tiêu thụ SelectList, tôi đưa nó cho một trình trợ giúp tùy chỉnh sử dụng trình trợ giúp DropDownList tiêu chuẩn. Vì vậy, một giải pháp khá nhẹ imo. Đoán nó phù hợp với tinh thần ASP.Net MVC tại thời điểm viết; khi không hài lòng, hãy cuộn của riêng bạn ...

public static string DropDownListEx(this HtmlHelper helper, string name, SelectList selectList, object selectedValue) 
{ 
    return helper.DropDownList(name, new SelectList(selectList.Items, selectList.DataValueField, selectList.DataTextField, selectedValue)); 
} 
4

Bởi vì đây là một kết quả cao như vậy trong Google, tôi đang cung cấp những gì tôi tìm thấy để làm việc ở đây (mặc dù tuổi):

Nếu bạn đang sử dụng một gõ mạnh Xem (tức là Model có một kiểu giao), SelectedValue được cung cấp cho Constructor của SelectList được ghi đè bởi giá trị của đối tượng được sử dụng cho Model của trang.

Điều này hoạt động tốt trên trang chỉnh sửa, nhưng không phải cho Tạo khi bạn muốn chọn trước giá trị cụ thể, do đó, một cách giải quyết đơn giản là gán giá trị chính xác cho đối tượng được tạo mặc định mà bạn chuyển đến chế độ xem làm Mô hình. ví dụ:

var model = new SubjectViewModel() 
{ 
    Subject = new Subject(), 
    Types = data.SubjectTypes.ToList() 
} 
model.Subject.SubjectType = model.Types.FirstOrDefault(t => t.Id == typeId); 
ViewData.Model = model; 
return View(); 

để mã trong tôi Create Xem trông như thế này:

Html.DropDownListFor(model => model.Subject.SubjectTypeId, new SelectList(model.Types, "Id", "Name")) 

trả về danh sách thả xuống với giá trị tôi được giao như SelectedValue trong danh sách.

4

Tôi biết đó là một câu hỏi cũ nhưng có thể giúp ai đó ở ngoài đó. Tôi đã làm những gì trông giống như những gì Erik đã làm. Tôi chỉ cần tạo một SelectList mới từ tôi hiện có một ...

SelectList myList = GetMySelectList(); 
SelectListItem selected = myList.FirstOrDefault(x => x.Text.ToUpper().Contains("UNITED STATES")); 
if (selected != null) 
{ 
    myList = new SelectList(myList, "value", "text", selected.Value); 
} 
0

Tôi đồng ý với @awrigley và những người khác rằng nó là tốt hơn để tải các giá trị được lựa chọn bằng cách sử dụng constructor SelectList trong trường hợp thông thường khi bạn có một DropDownList đơn . Tuy nhiên, đôi khi, bạn cần đặt giá trị đã chọn trên chế độ xem, chẳng hạn như khi bạn có một trang có n trình đơn thả xuống giống hệt nhau. Vì việc tạo bộ sưu tập như vậy trong bộ điều khiển là không thực tế và thậm chí có thể không biết trước bao nhiêu trình đơn thả xuống mà bạn cần, một cách tiếp cận tốt hơn là tạo một cá thể trong viewmodel dưới dạng mẫu không có giá trị đã chọn và sau đó tự động tạo phần còn lại động trên chế độ xem.

Tôi thường xuyên gặp sự cố này khi lặp qua danh sách các mục con trên chế độ xem chỉnh sửa khi trẻ cần trình đơn thả xuống. Trong những trường hợp như vậy, bạn có thể làm điều này như thế này với một dòng mã:

@Html.DropDownListFor(x => myViewModelFieldName, new SelectList(Model.MyRawSelectListFromMyViewModel.Select(x=> new {x.Value, x.Text}), "Value", "Text", TheValueYouWantToSelect)) 
Các vấn đề liên quan