2

我有一個Telerik MVC網格,在一個帶有Razor的MVC 3應用程序中,它正在受到Ajax綁定。我現在正在嘗試向它添加一個下拉列表列,以便用戶可以在編輯模式下使用它,但無法弄清楚。網格顯示產品列表,我希望下拉列表包含產品可以關聯的ProductCategories集合。我已經呆了好幾個小時了,而且我沒有想法。我真的希望這裏的某個人能夠幫助:)Telerik MVC Grid:如何在列中使用DropDownList?

我一直在引用一個Telerik演示,它位於here

我認爲掛我的部分是在演示使用的幫助視圖中。在演示中,這被稱爲「ClientEmployee(Editor)」。在我的情況下,我已經把幫手放在一個名爲「ProductCategoryDropList.cshtml」的文件中。在這個幫手中,我很難讓DropDownList正確綁定。我想這可能是因爲我沒有設置正確的數據的BindTo()方法。我在下面的示例DropDownList Helper代碼中標記了這個混淆點,將「SomeCollectionReference」作爲「新的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這裏的」 未來到我正在嘗試使用的列。

@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")) 
) 

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

我問了Telerik的支持人員。以下是他們給我的答案:

該模型爲空,因爲DropDownList部分視圖呈現爲 以進行ajax編輯。在這種情況下,網格預先顯示所有局部視圖編輯器模板,以便它可以在客戶端使用它們。在這種情況下, 模型將爲空。如果您使用服務器綁定和編輯模式 將被設置爲正確的值。

在這一點上,我將接受這個職位作爲我的問題的答案。不幸的是,在這種情況下我必須接受我自己的答案,但是......好吧,我沒有得到任何其他人可以選擇:)

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代碼放入網格創建代碼中,DropDownList根本不起作用。

那麼,我還有其他選擇嗎?

1

目前我面臨同樣的問題,你寫,它是真的真正是Telerik傢伙給你寫的。部分視圖在服務器上預先渲染(包含內容)。如果允許值的列表是靜態的,這可能是足夠的解決方案,但是...

...想象一下,您希望爲每個網格行使用不同的允許值列表。在這種情況下,這個概念是不可行的...

由於網格內只有一個組合(每列),我發現只有一個解決方案是處理onEdit網格事件,您可以使用AJAX將組合框綁定到允許的值。在grid onEdit處理程序中,您可以訪問正確行的所有數據字段,因此您可以將它們用於綁定目的。

問候,Ondrej。

+0

偉大的信息,翁德里。您是否可以用一兩個例子來更新這篇文章,說明您所描述的內容? – campbelt