【问题标题】:Control creation based on model value in MVC4MVC4中基于模型值的控件创建
【发布时间】:2020-01-01 18:56:02
【问题描述】:

在我的数据库中,我有一个名为 control_id 的列,其中包含 1、2、3、4 之类的值。基于这个值,我必须生成文本框、下拉列表和复选框等控件。 (例如,如果我的 control_id 为 1,则必须生成文本框,而为 2,则需要生成下拉列表等)我对 MVC 完全陌生。谁能指出我实施此方案的正确方向?

【问题讨论】:

    标签: asp.net-mvc-4


    【解决方案1】:
    1. 为控件类型创建一个枚举

      public enum ControlTypes  
      {
          TextBox  = 1,
          Dropdown = 2,
          CheckBox = 3,
          Label = 4
          // Define other control types  
      }
      
    2. 创建用于处理所有控件类型的基类。

      public class DynamicControlsBase
      {
          public virtual string FieldLabel { get; set; }
      
          public string ControlValue { get; set; }
          // For dropdown
          public virtual List<SelectListItem> ValueList { get; set; }
      
          // Likewise implement the other required property that the control uses
      }
      
    3. 为每个控件创建一个视图模型,现在用于文本框

       // Textbox deriving class    
       public class TextBoxViewModel : DynamicControlsBase 
       {
           public override string FieldLabel
           {
           get
           {
               return base.FieldLabel;
           }
           set
           {
               base.FieldLabel = value;
           }
      }
      
      public override List<SelectListItem> ValueList
      {
          get
          {
              return base.ValueList;
          }
          set
          {
              base.ValueList = value;
          }
      } 
      
      //View model for Label field 
      public class LabelViewModel : DynamicControlsBase 
      {
          public override string FieldLabel { get; set; } 
      }
      
    4. 为每个控件创建一个视图模型,这里是下拉菜单。

      public class DropdownViewModel : DynamicControlsBase   
      {
          public override string FieldLabel { get; set; }
      
          public override List<SelectListItem> ValueList
          {
              get
              {
                  return base.ValueList;
              }
              set
              {
              base.ValueList = value;
              }
          }
      }
      
    5. 现在在 Views>>Shared 下创建一个名为“EditorTemplates”的文件夹。

    6. 在该文件夹中,为每个视图模型(文本框和下拉菜单等)创建一个与 ViewModel ex 同名的视图。 TextBoxViewModel.cshtml,并为下拉和其他控件做同样的事情。

       @model MVCSample.Models.TextBoxViewModel 
       @Html.TextBoxFor(m => m.ControlValue)
      
    7. 在控制器操作方法中,为每个相应的视图模型分配值,如下所示,并将其传递给视图。

      DynamicControlsBase dcb = new TextBoxViewModel
      {
          ControlValue = "Test"
      };
      
      dcb = new DropdownViewModel
      {
           ControlValue = "Test",
           ValueList = new List<SelectListItem>
           {
                new SelectListItem
                {
                     Text = "Test",
                     Value= "1"
                },
                new SelectListItem
                {
                     Text = "Text",
                     Value= "1"
                }
           }
      };
      
    8. 在实际视图中,使用 html helper 'EditorFor' 渲染控件,

      @Html.EditorFor(m => m.DynamicControlsBase)
      

    在控制器中修改GetControl方法为,

    private DynamicControlsBase GetControl(string controlType, DataTable tableData = null, List<SelectListItem> controlValue = null)
    {
        if (controlType.Equals(Convert.ToString((int)ControlTypes.TextBox)))
        {
            return new TextBoxViewModel
            {
                ControlValue = tableData.AsEnumerable().Where(a => a.Field<int>("Control_id").Equals(int.Parse(controlType))).Select(a => a.Field<string>("Value")).FirstOrDefault(),
                FieldLabel = tableData.AsEnumerable().Where(a => a.Field<int>("Control_id").Equals(int.Parse(controlType))).Select(a => a.Field<string>("FieldLabel")).FirstOrDefault()
            };
        }
        else if (controlType.Equals(Convert.ToString((int)ControlTypes.Dropdown)))
        {
            return new DropdownViewModel
            {
                ControlValue = tableData.AsEnumerable().Where(a => a.Field<int>("Control_id").Equals(int.Parse(controlType))).Select(a => a.Field<string>("Value")).FirstOrDefault(),
                FieldLabel = tableData.AsEnumerable().Where(a => a.Field<int>("Control_id").Equals(int.Parse(controlType))).Select(a => a.Field<string>("FieldLabel")).FirstOrDefault(),
                ValueList = controlValue
            };
        }
        if (controlType.Equals(Convert.ToString((int)ControlTypes.Label)))
        {
            return new LabelViewModel
            {
                ControlValue = tableData.AsEnumerable().Where(a => a.Field<int>("Control_id").Equals(int.Parse(controlType))).Select(a => a.Field<string>("Value")).FirstOrDefault(),
                FieldLabel = tableData.AsEnumerable().Where(a => a.Field<int>("Control_id").Equals(int.Parse(controlType))).Select(a => a.Field<string>("FieldLabel")).FirstOrDefault()
            };
        }
    
        return new DynamicControlsBase();
    }
    

    【讨论】:

    • 是的。我只试过了。但是获得所有控制的 Label_field 。在 Enum 类中,对于 1、2、3,您定义了控件类。但是对于标签如何定义呢?我正在努力为每个控件带来相应的 label_field。 Profile_field 列必须转换为与相应控件的列名称相同名称的标签。请再次给我正确的方向。
    • 我之前误解了您的请求,因为我认为您希望为每个控件显示标签,如果我现在正在放置用于添加新标签字段的代码,就像其他控件一样。请查看更新后的答案。
    • 没有结果。只是显示控件。
    • @Html.LabelFor(m=>m.FieldLabel)。我在 LabelViewModel.cshtml 中使用了这段代码
    • 使用 @Html.DisplayFor(m=>m.FieldLabel) 来显示字段标签和标签控件值 @Html.DisplayFor(m=>m.ControlValue) 就像在其他编辑器模板中使用的一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 1970-01-01
    相关资源
    最近更新 更多