我有一个Telerik MVC网格,在一个带有Razor的MVC 3应用程序中,它正在被Ajax绑定。我现在正在尝试向其添加一个下拉列列,以便用户可以在编辑模式下使用它,但无法弄清楚如何。网格显示产品列表,我希望下拉列表包含ProductCategories的集合,Product可以与之关联。我已经在这几个小时了,我没有想法。我真的希望有人可以提供帮助:)
我一直在引用位于here的Telerik演示。
我认为引起我兴趣的部分是在演示使用的帮助视图中。在演示中,这称为“ClientEmployee(编辑器)”。在我的例子中,我将帮助器放在一个名为“ProductCategoryDropList.cshtml”的文件中。在这个帮助器中,我很难让DropDownList正确绑定。我想这可能是因为我没有以某种方式使用正确的数据设置BindTo()方法。我在下面的示例DropDownList Helper代码中标记了这一点,其中“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())
});
}
查看:
这有点长,但我试图通过在我尝试使用的列旁边放置“//&lt; --- 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 Helper:
@model Models.PresentationModels.ProductPresentationModel
@(Html.Telerik().DropDownList()
.Name("ProductCategoryName")
.BindTo(new SelectList(<SomeCollectionReference>, "ProductCategoryID", "ProductCategoryName"))
)
ProductMapper:
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;
}
答案 0 :(得分:1)
我设法解决了这个问题,但我还有一个问题。这是我为了让它发挥作用所做的改变:
在控制器中创建一个ViewData对象,就像这样...
public ActionResult Index()
{
// ViewData object here ...
ViewData["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()
{
// ViewData object here ...
ViewData["ProductCategories"] = new SelectList(_productCategoryService.GetActiveProductCategories(), "ProductCategoryID", "ProductCategoryName");
return View(new GridModel<ProductPresentationModel>
{
Data = _mapper.MapAsList(_productService.GetProducts().ToList())
});
}
然后,我在DropDownListHelper中使用了ViewData对象,就像这样......
@using System.Collections
@model Models.PresentationModels.ProductPresentationModel
@(Html.Telerik().DropDownList()
.Name("ProductCategoryName")
.BindTo(new SelectList((IEnumerable)ViewData["ProductCategories"], "Value", "Text"))
);
我现在的问题是......我是否必须使用ViewData对象?我希望能够使用我的模型中的属性。但是,由于某种原因,我的模型在Helper文件中总是为NULL。而且,如果我尝试将DropDownList代码放在Grid创建代码中,DropDownList根本不起作用。
那么,我还有其他选择吗?
答案 1 :(得分:1)
目前我遇到的问题与你写的一样,而且Telerik的人写的对你来说确实如此。部分视图在服务器上预呈现(包括内容)。如果允许值列表是静态的,那么这可能是足够的解决方案,但是......
...想象一下,您希望每个网格行都有不同的允许值列表。在这种情况下,这个概念是不可行的......
由于网格中只有一个组合(每列),我发现只有一个解决方案是处理onEdit网格事件,您可以使用AJAX将组合框数据绑定到允许的值。在grid onEdit处理程序中,您可以访问正确行的所有数据字段,因此您可以将它们用于绑定目的。
问候,Ondrej。
答案 2 :(得分:0)
我问Telerik的好支持人员。以下是他们给我的答案:
Model为null,因为呈现了DropDownList局部视图 用于ajax编辑。在这种情况下,网格会预渲染所有局部视图 编辑器模板,以便它可以在客户端使用它们。在这种情况下 模型将为null。如果您使用服务器绑定并编辑模型 将被设置为正确的值。
此时,我将接受这篇文章作为我的问题的答案。不幸的是,在这种情况下我必须接受我自己的答案,但是......好吧,我没有得到任何其他人可供选择:)