У меня есть сетка Telerik MVC в приложении MVC 3 с Razor, которое связано с Ajax. Сейчас я пытаюсь добавить к нему столбец выпадающего списка, чтобы пользователи могли использовать его в режиме редактирования, но не могу понять, как это сделать. В сетке отображается список продуктов, и я хочу, чтобы выпадающий список содержал набор категорий продуктов, с которыми может быть связан продукт. Я занимаюсь этим уже несколько часов, и у меня нет идей. Я очень надеюсь, что кто-то здесь может помочь :)
Я ссылался на демо-версию Telerik, которая находится здесь.
Я думаю, что часть, которая вешает меня, находится в представлении справки, которое используется в демо. В демо это называется "ClientEmployee(Editor)". В моем случае я поместил помощника в файл с именем «ProductCategoryDropList.cshtml». В этом помощнике мне трудно заставить DropDownList правильно связываться. Я думаю, это может быть потому, что я каким-то образом не устанавливаю метод BindTo() с правильными данными. Я отметил эту путаницу в приведенном ниже примере кода вспомогательной программы DropDownList с параметром SomeCollectionReference в качестве первого параметра в вызове конструктора new SelectList(). Когда я пытаюсь поместить «Модель» в это место, я получаю исключение NullReferecne. Когда я пытаюсь получить доступ к данным ViewBag, содержащим список, я получаю сообщение, похожее на «В SelectList нет столбца ProductCategoryID» или что-то в этом роде. Итак, я не уверен, что еще попробовать.
Я не уверен, насколько ясно это описание моей проблемы, но чтобы быть полным, я включил код, который я считаю уместным ниже.
Контроллер:
public ActionResult Index()
{
ViewBag.ProductCategories = new SelectList(_productCategoryService.GetActiveProductCategories(), "ProductCategoryID", "ProductcategoryName");
var products = _productService.GetProducts().ToList();
var presentationModel = _mapper.MapAsList(products);
return View(presentationModel);
}
//
// GET: /Product/
[GridAction]
public ViewResult _Index()
{
ViewBag.ProductCategories = new SelectList(_productCategoryService.GetActiveProductCategories(), "ProductCategoryID", "ProductcategoryName");
return View(new GridModel<ProductPresentationModel>
{
Data = _mapper.MapAsList(_productService.GetProducts().ToList())
});
}
Просмотр:
Это немного длинно, но я попытался упростить его, поместив «// ‹--- DropList Here» рядом со столбцом, с которым я пытаюсь работать.
@model IEnumerable<Models.PresentationModels.ProductPresentationModel>
@(Html.Telerik().Grid(Model).HtmlAttributes(new { style = "width: 100%;" })
// Give the Grid an HTML id attribute value
.Name("ProductGrid")
// Establish the promiry key, to be used for Insert, Update, and Delete commands
.DataKeys(dataKeys => dataKeys.Add(p => p.ProductID))
// Add an Insert command to the Grid Toolbar
.ToolBar(commands => commands.Insert().ButtonType(GridButtonType.ImageAndText))
// Using Ajax Data Binding to bind data to the grid
.DataBinding(dataBinding => dataBinding
// Ajax Binding
.Ajax()
.Select("_Index", "Product")
// Home.Insert inserts a new data record
.Insert("Create", "Product")
// Home.Update updates an existing data record
.Update("Edit", "Product")
// Home.Delete deletes an existing data record
.Delete("Delete", "Product")
)
.Columns(columns =>
{
columns.Bound(p => p.ProductName).Width(120);
columns.Bound(p => p.ProductDescription).Width(150);
columns.Bound(p => p.PricePerMonth).Width(120);
columns.Bound(p => p.ProductImagePath).Width(150)
columns.Bound(p => p.ProductActive).Width(120)
.ClientTemplate("<input type='checkbox' disabled='disabled' name='Active' <#= ProductActive ? checked='checked' : '' #> />");
columns.Bound(p => p.ProductCategoryName); // <--- DropList Here
columns.Command(commands =>
{
commands.Edit().ButtonType(GridButtonType.Image);
commands.Delete().ButtonType(GridButtonType.Image);
});
})
.Editable(editing => editing.Mode(GridEditMode.PopUp))
.ClientEvents(events => events.OnEdit("onEdit"))
.Pageable()
.Scrollable()
.Sortable()
.Filterable()
)
@section HeadContent {
<script type="text/javascript">
function onEdit(e) {
$(e.form).find('#ProductCategoryName').data('tDropDownList').select(function (dataItem) {
return dataItem.Text == e.dataItem['ProductCategoryName'];
});
}
</script>
}
Модель:
[DisplayName(@"Category Name")]
[UIHint("ProductCategoryDropList"), Required]
[StringLength(255, ErrorMessage = @"Product Category Name cannot be more than 255 characters in length")]
public string ProductCategoryName
{
get
{
string name = string.Empty;
if (_model.ProductCategory != null)
{
name = _model.ProductCategory.ProductCategoryName;
}
return name;
}
set
{
if (_model.ProductCategory != null)
{
_model.ProductCategory.ProductCategoryName = value;
}
}
}
Помощник DropList:
@model Models.PresentationModels.ProductPresentationModel
@(Html.Telerik().DropDownList()
.Name("ProductCategoryName")
.BindTo(new SelectList(<SomeCollectionReference>, "ProductCategoryID", "ProductCategoryName"))
)
Карта продукта:
public List<ProductPresentationModel> MapAsList(List<Product> products)
{
//var categoryList = new SelectList(_productCategoryService.GetProductCategories().ToList(), "ProductCategoryID", "ProductCategoryName");
var presentationModels = products
.Select(x => new ProductPresentationModel()
{
ProductID = x.ProductID,
ProductCategoryID = ((x.ProductCategory != null) ? x.ProductCategory.ProductCategoryID : 0),
ProductCategoryName = ((x.ProductCategory != null) ? x.ProductCategory.ProductCategoryName : String.Empty),
ProductName = x.ProductName,
ProductDescription = x.ProductDescription,
PricePerMonth = x.PricePerMonth,
ProductImagePath = x.ProductImagePath,
ProductActive = x.ProductActive,
ProductCategories = new SelectList(_productCategoryService.GetProductCategories().ToList(), "ProductCategoryID", "ProductCategoryName")//categoryList
}).ToList();
return presentationModels;
}