首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在MVC3中基于XML文件动态创建控件

如何在MVC3中基于XML文件动态创建控件
EN

Stack Overflow用户
提问于 2011-06-13 10:52:00
回答 3查看 39.3K关注 0票数 28

我有一个XML文件作为XML格式存储在数据库中,其中包含一些控件,如下拉文本框,标签文本区域等,可能有初始值,也可能没有初始值。因此,我的目标是读取XML文件,并且基于控件类型,我需要动态创建该控件并关联初始值(如果有的话),并且必须在视图中显示页面的预览。任何人,请帮助我如何在MVC3中为这个场景动态创建控件。

例如:我的xml文件看起来像这样。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8" ?>
  <controls>
    <control>
      <type name="label">
        <property name="Visible" value="true"/>
        <property name="ID" value="Label1"/> 
         .
         .
         .
      </type>
    </control>
    <control>
      <type name="TextBox">
        <property name="Visible" value="true"/>
        <property name="ID" value="TextBox1"/>
        .
        .
        .
      </type>
    </control>
    .
    .
    .
  </controls>

提前谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-13 17:26:14

我会试着为你提供一些提示,可能会给你一些想法。

像往常一样,让我们从定义一个表示UI的视图模型开始:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyViewModel
{
    public ControlViewModel[] Controls { get; set; }
}

public abstract class ControlViewModel
{
    public abstract string Type { get; }
    public bool Visible { get; set; }
    public string Label { get; set; }
    public string Name { get; set; }
}

public class TextBoxViewModel : ControlViewModel
{
    public override string Type
    {
        get { return "textbox"; }
    }
    public string Value { get; set; }
}

public class CheckBoxViewModel : ControlViewModel
{
    public override string Type
    {
        get { return "checkbox"; }
    }
    public bool Value { get; set; }
}

public class DropDownListViewModel : TextBoxViewModel
{
    public override string Type
    {
        get { return "ddl"; }
    }
    public SelectList Values { get; set; }
}

因此,我们已经定义了一些我们想要在应用程序中处理的基本控件。下一步是有一个仓库方法,它将查询数据库,获取XML,然后是一个映射层,最终将为我们提供视图模型的一个实例。我把它留在这个答案的范围之外,因为有很多方法可以实现它(XmlSerializer,XDocument,XmlReader,...)。

我假设您已经有了视图模型的一个实例。如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public ActionResult Index()
{
    var model = new MyViewModel
    {
        Controls = new ControlViewModel[]
        {
            new TextBoxViewModel 
            { 
                Visible = true,
                Label = "label 1",
                Name = "TextBox1", 
                Value = "value of textbox" 
            },
            new CheckBoxViewModel 
            { 
                Visible = true,
                Label = "check label",
                Name = "CheckBox1", 
                Value = true 
            },
            new DropDownListViewModel 
            { 
                Visible = true,
                Label = "drop label",
                Name = "DropDown1", 
                Values = new SelectList(
                    new[] 
                    {  
                        new { Value = "1", Text = "text 1" },
                        new { Value = "2", Text = "text 2" },
                        new { Value = "3", Text = "text 3" },
                    }, "Value", "Text", "2"
                ) 
            }
        }
    };
    return View(model);
}

为了说明这个概念,我硬编码了一些值,但通常情况下,一旦实现了存储库和映射层,这个控制器操作就会如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public ActionResult Index()
{
    string xml = _repository.GetControls();
    var model = Mapper.Map<string, MyViewModel>(xml);
    return View(model);
}

好的,现在让我们移动到相应的Index.cshtml视图,它将包含表单:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@model MyViewModel
@using (Html.BeginForm())
{
    for (int i = 0; i < Model.Controls.Length; i++)
    {
        if (Model.Controls[i].Visible)
        {
            <div>
                @Html.HiddenFor(x => x.Controls[i].Type)
                @Html.HiddenFor(x => x.Controls[i].Name)
                @Html.EditorFor(x => x.Controls[i])
            </div>
        }
    }
    <input type="submit" value="OK" />
}

好了,现在我们可以为我们想要处理的控件定义相应的编辑器模板:

  • ~/Views/Shared/EditorTemplates/TextBoxViewModel.cshtml

@model AppName.Models.TextBoxViewModel @Html.LabelFor(x => x.Value,Model.Label) @Html.TextBoxFor(x =>

@model AppName.Models.CheckBoxViewModel @Html.CheckBoxFor(x => x.Value) @Html.LabelFor(x => x.Value,模型

@model AppName.Models.DropDownListViewModel @Html.LabelFor(x => x.Value,Model.Label) @Html.DropDownListFor(x => x.Value,Model.Label

到现在为止还好。在此阶段,您应该能够呈现包含动态控件的窗体。当然,这样的表单对任何人来说都是非常无用的。更好的是可以对这个表单执行POSTing操作,并捕获用户在控制器操作中输入的值,这样我们就可以处理它们了。

控制器操作将如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[HttpPost]
public ActionResult Index(MyViewModel model)
{
    ... process the values
}

现在这样做很好,但当然不会起作用,因为ControlViewModel视图模型是一个抽象类,而默认的模型绑定器不知道实例化哪个具体的实现。因此,我们需要通过编写自定义模型绑定器来帮助他实现=>:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ControlModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        var type = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Type");
        object model = null;
        switch (type.AttemptedValue)
        {
            case "textbox":
            {
                model = new TextBoxViewModel();
                break;
            }
            case "checkbox":
            {
                model = new CheckBoxViewModel();
                break;
            }
            case "ddl":
            {
                model = new DropDownListViewModel();
                break;
            }
            default:
            {
                throw new NotImplementedException();
            }
        };

        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType());
        return model;
    }
}

它将在Application_Start中注册并与ControlViewModel类型关联):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ModelBinders.Binders.Add(typeof(ControlViewModel), new ControlModelBinder());
票数 50
EN

Stack Overflow用户

发布于 2011-06-13 11:26:39

事实上,这看起来很简单。从数据库获取XML,对其进行解析并将其放入一些模型类中。这些类将包含控件数据。

接下来,创建局部视图,该视图将根据模型动态构建所需的控件。

最后,从HTML调用该操作,并将返回的jQuery放在适当的位置。

快点,简单点,不用再装了.

票数 0
EN

Stack Overflow用户

发布于 2011-06-13 12:40:19

您可以将一个模型传递给您的强类型视图,并在该助手中编写一个名为Html.ControlFor的html助手。您可以读取xml文件并创建控件(输入、选择等)。基于属性名称的匹配(其中属性名称与xml文件中的属性标签匹配)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6329461

复制
相关文章
如何在Linux中创建文件?多个文件创建操作命令。
如果文件file1.txt不存在,则上面的命令将创建该文件,否则,它将更改其时间戳。
用户5005176
2021/08/10
39.2K0
C#在WINForm程序中创建XML文件
string path = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
zls365
2021/02/26
2.4K0
如何在mybatis xml文件中定义局部变量?
mybatis定义全局变量只需要配置一下即可,那如何在mybatis xml文件中定义局部变量呢?这就需要使用<bind>标签了。
索码理
2022/12/28
3.2K0
如何在Java中创建临时文件?
在Java程序中,有时需要创建临时文件来暂存数据或者执行某些操作。Java提供了许多方式来创建临时文件。在本教程中,我们将介绍如何使用Java标准库来创建临时文件。
网络技术联盟站
2023/04/19
1.8K0
如何在Java中创建临时文件?
如何在PHP中解析XML
XML解析器是一个程序,它可以将XML文档或代码转换为XML文档对象模型(DOM)对象。
Lemon黄
2020/07/07
3.6K0
如何在 Linux 中创建带有特殊字符的文件?
在 Linux 系统中,创建文件是进行各种操作的基础。有时候,我们需要创建带有特殊字符的文件,例如包含空格、特殊符号或非ASCII字符的文件。本文将详细介绍在 Linux 中如何创建带有特殊字符的文件,以便您能够轻松地完成这样的任务。
网络技术联盟站
2023/07/14
7060
如何在 Linux 中创建带有特殊字符的文件?
如何在 Linux 中创建带有特殊字符的文件?
在 Linux 系统中,创建文件是进行各种操作的基础。有时候,我们需要创建带有特殊字符的文件,例如包含空格、特殊符号或非ASCII字符的文件。本文将详细介绍在 Linux 中如何创建带有特殊字符的文件,以便您能够轻松地完成这样的任务。
网络技术联盟站
2023/08/03
8050
如何在 Linux 中创建带有特殊字符的文件?
drools 手动创建kmoudle.xml文件
@Test public void test() { KieServices kieServices = KieServices.Factory.get(); KieResources resources = kieServices.getResources(); KieModuleModel kieModuleModel = kieServices.newKieModuleModel();//1 KieBaseModel baseM
ydymz
2018/09/10
1.5K0
winfrom如何在listview中添加控件
private Button btn = new Button(); private void Form1_Load(object sender, EventArgs e) { ListViewItem[] lvs = new ListViewItem[3]; lvs[0] = new ListViewItem(new string[] { "行1列1", "行1列2", "" }); l
码农阿宇
2018/04/18
2.6K0
JAVA框架中XML文件
我们应该在开头写返回结果 resultMap id="自己起的名字" type="返回的结果类型,此处为Department实体类"
阮键
2019/08/07
7630
Java中解析XML文件
树结构,有助于更好地理解、掌握,代码易于编写,在解析过程中树结构是保存在内存中,方便修改
头发还在
2023/10/16
2610
【DB笔试面试511】如何在Oracle中写操作系统文件,如写日志?
可以利用UTL_FILE包,但是,在此之前,要注意设置好UTL_FILE_DIR初始化参数。
AiDBA宝典
2019/09/30
28.8K0
【DB笔试面试511】如何在Oracle中写操作系统文件,如写日志?
基于DOM的XML文件解析类
最近公司做服务配置检查,特别是zookeeper配置里面关于数据库、redis、域名的配置。刚好还没弄过XML解析,所以顺手封装了一个工具类。
FunTester
2020/10/10
6890
基于DOM的XML文件解析类
TinyXML2读取和创建XML文件
TinyXML2是simple、small、efficient C++ XML文件解析库!方便易于使用,是对TinyXML的升级改写!源码见本人上传到CSDN的TinyXML2.rar资源:http://download.csdn.net/detail/k346k346/8500915,或者到官网下载:https://github.com/leethomason/tinyxml2。
恋喵大鲤鱼
2018/08/03
4.1K0
如何对动态创建控件进行验证以及在Ajax环境中的使用
首先给一个常规的动态创建控件,并进行验证的代码 [前端aspx代码] <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <htm
菩提树下的杨过
2018/01/22
7.8K0
使用Eclipse自动创建web.xml文件
很多时候用Eclipse写Web项目时候,忘记创建web.xml文件了,这就很难受了,下面两种方法教你如何使用Eclipse 自动创建web.xml文件。
浩Coding
2019/07/03
3K0
【C#】创建、解析 xml 文件(XmlDocument 方式)
本文使用 System.Xml 中的 XmlDocument 解析 xml 格式的文件。另外,由于我是粗略的看了下官方文档和一些博客,可能会有许多错误的地方,望指出。
全栈程序员站长
2022/09/06
1.7K0
【Groovy】Xml 反序列化 ( 使用 XmlParser 解析 Xml 文件 | 删除 Xml 文件中的节点 | 增加 Xml 文件中的节点 | 将修改后的 Xml 数据输出到文件中 )
在 【Groovy】Xml 反序列化 ( 使用 XmlParser 解析 Xml 文件 | 获取 Xml 文件中的节点和属性 | 获取 Xml 文件中的节点属性 ) 博客基础上 , 删除 Xml 文件中的节点信息 ;
韩曙亮
2023/03/30
6.2K0
【Groovy】Xml 反序列化 ( 使用 XmlParser 解析 Xml 文件 | 删除 Xml 文件中的节点 | 增加 Xml 文件中的节点 | 将修改后的 Xml 数据输出到文件中 )
点击加载更多

相似问题

使用MVC3创建动态控件

11

基于变量动态创建控件

13

基于XML创建动态XSL

13

如何在面板控件中动态创建控件

21

如何基于布局创建XML友好控件?

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文