簡體   English   中英

如何將下拉列表綁定到ASP.Net MVC C#中的動態生成的變量

[英]How to bind a drop down list to a dynamically generated variable in ASP.Net MVC C#

我們有一個使用動態自定義屬性定義系統中某些實體的屬性的應用程序。

因此,在某些情況下,我們需要動態填充表單字段(通常是下拉列表或復選框列表),最好在視圖中指定自定義屬性類型。

這個問題專門關於下拉列表。

這是我們正在嘗試做的事情:

ViewModel:

public class SearchViewModel
{
    #region Properties

    public Dictionary<string, SelectList> CustomPropertySelectLists { get; set; }
    public Dictionary<string, string> SelectedCustomProperties { get; set; }

    #endregion

    #region Constructors

    public SearchViewModel()
    {
        //Create the SelectedCustomProperties list and pre-populate with a blank item for each CustomPropertyType
        SelectedCustomProperties = new Dictionary<string, string>();
        foreach (CustomPropertyType cpt in Core.GetCustomPropertyTypes())
        {
            SelectedCustomProperties.Add(cpt.CustomPropertyTypeId, string.Empty); 
        }
    }

    #endregion
}

控制器:

public ActionResult Search(int searchId)
{
    var svm = new SearchViewModel();

    //Load selected custom property ids for this search
    if ( searchId > 0 )
    {
        Search s = Core.GetSearch(searchId);
        foreach ( CustomPropertyType cpt in Core.GetCustomPropertyTypes()) )
        {
            int cpid = s.GetBasicSearchCustomPropertyId(cpt.CustomPropertyTypeId);
            if ( cpid > 0 )
            {
                //NB assumes entries already present (i.e. were created in the constructor)
                svm.SelectedCustomProperties[cpt.CustomPropertyTypeId] = cpid.ToString();
            }
        }
    }

    //Load lists of all custom property select lists so the view can just dynamically use whichever ones it wants
    svm.CustomPropertySelectLists = Core.GetSelectListsForAllCustomPropertyTypes();

    return View(svm);
}

然后在視圖中:

@using (Html.BeginForm())
{
    <fieldset>
        <div class="row">
            <div class="col">
                @Html.DropDownListFor(m => m.SelectedCustomProperties["Sector"], Model.CustomPropertySelectLists["Sector"], "Sector", new { @class = "browser-default" })
            </div>
            <div class="col">
                @Html.DropDownListFor(m => m.SelectedCustomProperties["Location"], Model.CustomPropertySelectLists["Location"], "Location", new { @class = "browser-default" })
            </div>
        </div>
    </fieldset>
}

所有這些工作都可以填充動態定義的下拉列表。 我們甚至可以通過循環定義自定義屬性類型來動態定義要在運行時呈現的下拉列表,這些自定義屬性類型已定義為出現在系統的某些部分和/或使用存儲在系統其他位置的某些實體顯示。

但是,下拉列表中的選定值未獲取,可能是因為它試圖綁定到m => m.SelectedCustomProperties["Sector"]而不是綁定到標量變量屬性。

我意識到在我們的ViewModel中,我們可以有類似以下內容:

public string SelectedCustomPropertyIdSector { get; set; }

然后在控制器中填充SelectedCustomPropertyIdSector ,然后使用m => m.SelectedCustomPropertyIdSector綁定到下拉列表,但這會在一定程度上破壞系統中自定義屬性的動態特性,因為我們必須對ViewModel進行屬性編碼/ Controller取決於用途。

理想情況下,我們希望能夠編寫僅與數據庫中的“ CustomProperty”實體有關的通用,可重用的模型和控制器代碼,然后讓視圖通過引用中的自定義屬性類型ID來指定要使用的特定自定義屬性。視圖標記(和/或通過動態確定要在運行時呈現的下拉列表)。

僅當我們可以將DropDownListFor屬性綁定到動態生成的列表(由自定義屬性類型id引用)中的某物(而不是通常情況下的縮放器變量)時,這才可能實現,但這似乎是不可能的?

我是MVC的新手,但以我的經驗,下拉列表希望更新視圖模型的知名屬性,即您提到的標量SelectedCustomPropertyIdSector。

您是否嘗試過將SelectedCustomProperties包含為HiddenFor,以確保列表本身在發布后返回操作?

可能無法正常工作是因為視圖模型在頁面呈現后無法記住列表,並且沒有標量變量附加到該列表中可能是問題所在。

看來您對模型綁定有問題。 發布的Html在發布時無法綁定回模型。

您可能想看一下此博客文章http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

我自己沒有將項目綁定到Dictionary,而是必須綁定到IEnumerable<Object> 您可以嘗試創建CustomPropertyViewModel

public class CustomPropertyViewModel
{
    public string Filter { get; set; }
    public string SelectedValue { get; set; }
    public SelectList SelectList { get; set; }
}

您的SearchViewModel將包含

IEnumerable<CustomerPropertyViewModel> CustomProperties { get; set; }

並且您將在視圖中呈現類似

@for (int i = 0; i < Model.CustomPropeties.Count(); i++)
{
    @Html.HiddenFor(x => Model.CustomProperties[i].Filter
    @Html.DropdownListFor(x => Model.CustomProperties[i].SelectedValue,
        Model.CustomProperties[i].SelectList)
}

您可以嘗試使用@Html.DropDownList而不是@Html.DropDownListFor

 @Html.DropDownList("Sector", Model.CustomPropertySelectLists["Sector"], "Sector", new { @class = "browser-default" })

這樣提交的值將在回發操作中作為Request.Form["Sector"]

然后,您需要將其映射到您的屬性。 所以類似的事情應該起作用(我假設您可以自定義屬性名稱,因此可以自動向其中編寫一些代碼):

SelectedCustomProperties["Sector"] = Request.Form["Sector"]

編輯您可以自動執行下拉列表生成和順序模型綁定:

@for(var key in Model.CustomPropertySelectLists.Keys)
{
    @Html.DropDownList(key , Model.CustomPropertySelectLists[key], key , new { @class = "browser-default" })
}

在您的回發操作中:

var types = Core.GetCustomPropertyTypes()
foreach(var t in types)
{
    if(Request.Form.ContainsKey(t.CustomPropertyTypeId))
    {
        SelectedCustomProperties[t.CustomPropertyTypeId] = Request.Form[t.CustomPropertyTypeId]
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM