У меня есть простой словарь VB:
Dim MyOptions As New Dictionary(Of String, String) From {{"one", "ONE"}, {"two", "TWO"}, {"three", "THREE"}}
И я пытаюсь преобразовать его в тип SelectList для использования в помощнике Html.DropDownList, который генерирует HTML для списка выбора.
Я пробовал это:
Dim list As SelectList = New SelectList(MyOptions, "Key", "Value", "one") ' errors on this line
html.DropDownList("SomeList", list, "Simple List")
, что приводит к этой ошибке:
Привязка данных: 'Система.Строка 'не содержит свойства с именем' Key '.
И я пробовал это:
Dim list As SelectList = New SelectList(MyOptions.[Select](Function(x) New With {Key .Value = x.Key, Key .Text = x.Value}), "Value", "Text") ' errors on this line
html.DropDownList("SomeList", list, "Simple List")
Какие результатыв этой ошибке:
Открытый член 'Ключ' для типа 'Строка' не найден.
РЕДАКТИРОВАТЬ
Я, очевидно, упростил приведенный выше пример, немного проще.
Где-то в моем реальном коде словарь (из строки, строки) конвертируется в KeyValuePair (из String, Object).
Фактический код:
В классе я определяю это открытое свойство:
Public InputFilters As List(Of Dictionary(Of String, Object)) = Nothing ' stores the details of all the added filter types to be rendered
, и в этом же классе у меня есть этот метод:
Private Sub _Add(ByVal type As String, ByVal labelText As String, ByVal id As String, ByVal defaultValue As Object, ByVal additionalInputClass As String, ByVal placeholder As String, ByVal arrValues As String(), ByVal dictValues As Dictionary(Of String, String), ByVal checked As Boolean)
Dim normalizedValues As New Dictionary(Of String, String)
If dictValues.Count > 0 Then
For Each key As String In dictValues.Keys
normalizedValues.Add(key, dictValues(key))
Next
End If
If arrValues.Count > 0 Then
For Each val As String In arrValues
normalizedValues.Add(val, val)
Next
End If
Dim d = New Dictionary(Of String, Object) From {
{"type", type},
{"labelText", labelText},
{"id", id},
{"defaultValue", defaultValue},
{"additionalInputClass", additionalInputClass},
{"checked", checked}, {"placeholder", placeholder},
{"commonInputClass", CommonInputClass},
{"idPrefix", IdPrefix}}
d.Add("Values", normalizedValues) ' breakpoint and watch here shows d("Values") as type Dictionary(Of String, String)
InputFilters.Add(d) ' breakpoint and watch here shows InputFilters(0)("Values") as type KeyValuePair(Of String, Object)
End Sub
Обратите внимание на комментарии к последним двум строкам, как этогде происходит преобразование из словаря в KeyValuePair.
На странице просмотра бритвы я делаю это:
@For Each Filter As Dictionary(Of String, Object) In Model.InputFilters
@Html.BuildFilterInput(Filter)
Next
И вспомогательный HTML-код для BuildFilterInput выглядит следующим образом:
<Extension()>
Public Function BuildFilterInput(ByVal html As HtmlHelper, ByVal Filter As Dictionary(Of String, Object)) As IHtmlString
Dim id As String = (Filter("idPrefix") & Filter("id")).ToString()
Dim Result As String = ""
Result &= "<div class=""col-md-6 col-lg-4 report-filter-item-wrapper"">" & vbCrLf
Result &= " <div class=""form-group"">" & vbCrLf
Result &= " " & html.Label(id, Filter("labelText").ToString).ToString() & vbCrLf
Result &= " "
Select Case Filter("type")
Case "text"
Result &= html.TextBox(id, Filter("defaultValue").ToString(), New With {Key .name = id, Key .[class] = "form-control" & If(Filter("additionalInputClass").ToString = "", "", " " & Filter("additionalInputClass").ToString()) & If(Filter("commonInputClass").ToString() = "", "", " " & Filter("commonInputClass").ToString()), Key .placeholder = If(Filter("placeholder").ToString() = "", "", Filter("placeholder").ToString())}).ToString() & vbCrLf
Case "select"
Dim list As SelectList = New SelectList(Filter.Values, "Key", "Value", "ME") ' this is where it blows up because Filter.Values is not a dictionary !!!!!!
Result &= html.DropDownList(id, list, "What is this").ToString() & vbCrLf
End Select
Result &= " </div>" & vbCrLf
Result &= "</div>" & vbCrLf
Return html.Raw(Result)
End Function