2013-09-11 3 views
1

Я использую erichynds Multi Select Widget, чтобы создать приятный стиль для моего MultiSelectList. Но мой вопрос (кажется) не связан.MVC Razor MultiSelectList Получение/настройка SelectedValue

Я пытаюсь выполнить каждый вопрос DemographicQuestionFilter, перечислить ответ DemographicResponseFilter и уметь получать/публиковать выбранные предметы вместе с моей моделью DemographicFilterViewModel. Проблема, с которой я сталкиваюсь, заключается в том, что когда я устанавливаю фильтры для элемента-1 (индекс 0) в списке, он отлично работает, когда я устанавливаю элемент-2 (индекс 1), он работает только, если элемент-1 также задан, если элемент -1 не задано, то объект DemographicFilters имеет значение NULL. Я предполагаю, что могу переключать типы, или что у меня отсутствует что-то основное.

Как это сделать, чтобы список, содержащий выбранные элементы для n вопроса, не зависел от n-1, также имеющего выбранный элемент?

Вот мои ViewModel объекты:

Родитель:

public class DemographicFilterViewModel 
{ 
    public int TaskID { get; set; } 
    public List<DemographicQuestionFilter> DemographicFilters { get; set; } 
} 

Ребенок:

public class DemographicQuestionFilter 
{ 
    public string Question { get; set; } 

    public List<DemographicResponseFilter> Responses { get; set; } 

    public List<SelectListItem> selectListItems { get; set; } 

    public List<int> SelectedItems { get; set; } 
} 

Внук:

public class DemographicResponseFilter 
{ 
    public int ResponseID { get; set; } 
    public string Response { get; set; } 
} 




Вид:

@Html.HiddenFor(m => m.TaskID) 
if (Model.DemographicFilters != null) 
{ 
    for (int i = 0; i < Model.DemographicFilters.Count; i++) 
    { 
     @Html.HiddenFor(model => model.DemographicFilters[i].SelectedItems) 
     @Html.DisplayTextFor(m => m.DemographicFilters[i].Question) 
     <br /> 
     @Html.ListBoxFor(model => model.DemographicFilters[i].SelectedItems, new MultiSelectList(Model.DemographicFilters[i].Responses, "ResponseID", "Response", Model.DemographicFilters[i].SelectedItems), new { Multiple = "multiple" }) 
     <br /> 
     <br /> 
    } 
} 

Вот что визуализируется на экране (только так вы можете попробовать следовать тому, что я делаю): http://i.imgur.com/ZefpLy1.png?1

Редактировать: Вопрос в том, когда вид сообщений обратно в контроллер, представление отображается правильно, но на HttpPost значения в [n] SelectedItems зависят от [n-1] SelectedItems, имеющих значение,

Если [i] SelectedItems пуст (ничего не выбрано), то каждый [> i] SelectedItems имеет значение null, даже если значения заданы в HttpGet ...

HtmlHelper Расширение:

#region Usings 

using System; 
using System.Collections.Generic; 
using System.Linq.Expressions; 
using System.Web.Mvc.Html; 
using System.Web.Mvc; 

#endregion 

namespace Extensions 
{ 
    public static class HtmlHelperExtensions 
    { 
     public static MvcHtmlString HiddenEnumerableFor<TModel, TEnumType>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, IEnumerable<TEnumType>>> expression) 
     { 
      return htmlHelper.Hidden(htmlHelper.NameFor(expression).ToHtmlString(), 
       string.Join(",", expression.Compile().Invoke(htmlHelper.ViewData.Model) ?? new TEnumType[0])); 
     } 
    } 
} 



ответ

1

Мой ответ на это расширение на то, что отправил Взант Сундаралингам в своем ответе, что HiddenFor не будет работать с массивами. Я пошел вперед и создал функцию, которая ведет себя как hiddenFor для перечислимых свойств.

@functions 
{ 
    public MvcHtmlString HiddenEnumerableFor<TModel, TEnumType>(
     HtmlHelper<TModel> htmlHelper, 
     Expression<Func<TModel, IEnumerable<TEnumType>>> expression) 
    { 

     return htmlHelper.Hidden(htmlHelper.NameFor(expression).ToHtmlString(), 
      string.Join(",", expression.Compile().Invoke(htmlHelper.ViewData.Model) ?? new TEnumType[0])); 
    } 
} 

Заменить

@Html.HiddenFor(model => filter.SelectedItems) 

С

@HiddenEnumerableFor(Html, m => m.DemographicFilters[i].SelectedItems) 

Вы также могли бы преобразовать это в метод расширения путем добавления его в статический класс, и добавление this перед первым параметром.Таким образом, это будет выглядеть очень похоже на HiddenFor

@Html.HiddenEnumerableFor(m => m.DemographicFilters[i].SelectedItems) 
+0

Я проверю ваше решение завтра, но не должно быть никаких нулей в представлении. Просмотр корректно отображает данные и отображает их правильно, это PostBack, который отправляет сообщения с отсутствующими значениями, которые установлены в представлении. Поэтому, если у filter.SelectedItems есть значение, тогда filter.index -1.SelectedItems должны иметь значение (должны быть выбраны элементы). – Faraday

+0

Хорошо, что мой ответ вам не поможет, опубликуйте эту информацию в своем вопросе, потому что это было непонятно. –

+0

@ Html.HiddenEnumerableFor (m => m.DenographicFilders [i] .SelectedItems): Он говорит, что не может найти HiddenEnumerableFor (Autocomplete тоже не находит его). - Я поставил свой метод расширения на вопрос, если я что-то пропустил! – Faraday

2

HiddenFor не может быть использован для ListBoxFor так вот обходной путь я попытался исправить эту проблему.

Заменено

@Html.HiddenFor(model => filter.SelectedItems) 

С

@Html.Hidden(string.Format("DemographicFilters[{0}].SelectedItems", i), "-1") 

Проблема с этим подходом является то, что ваши DemographicFilters.SelectedItems будет иметь дополнительный ряд -1 добавил к нему, необходимо добавить код, чтобы исключить -1 строку ,

+0

Я попробую это утром. Я попытался создать список с единственным «0» int в нем в качестве другого обходного пути (я удалил скрытое поле), но это не помогло. Я отправлю обратно завтра, как только я пробовал это :-) – Faraday

+0

Ваше решение сработало, я просто предпочел сделать это в стиле @ html.HiddenBlah :) Спасибо! – Faraday

Смежные вопросы