Asp.net mvc 在MVC中,如何开发类似于老式用户控件的东西?

Asp.net mvc 在MVC中,如何开发类似于老式用户控件的东西?,asp.net-mvc,asp.net-mvc-4,architecture,user-controls,Asp.net Mvc,Asp.net Mvc 4,Architecture,User Controls,好吧,这个问题可能看起来太宽泛了,但我会更具体一些 我有一个树状视图,希望是用来显示一些层次结构。此外,我还实现了一些行为,例如检查父节点时是否会打开折叠的节点,或者是否是延迟加载,或者是否会自动加载所有内容。但我不想让这些行为被硬编码。我想创建一个可自定义的控件。类似Telerik Kendo UI的功能。他们开发了一个控件,可以这样使用: @(Html.Kendo().MaskedTextBox() .Name("phone_number") .Mask("(999) 000

好吧,这个问题可能看起来太宽泛了,但我会更具体一些

我有一个树状视图,希望是用来显示一些层次结构。此外,我还实现了一些行为,例如检查父节点时是否会打开折叠的节点,或者是否是延迟加载,或者是否会自动加载所有内容。但我不想让这些行为被硬编码。我想创建一个可自定义的控件。类似Telerik Kendo UI的功能。他们开发了一个控件,可以这样使用:

@(Html.Kendo().MaskedTextBox()
    .Name("phone_number")
    .Mask("(999) 000-0000")
    .Value("555 123 4567")
)
@(Html.Foo().HierarchyView()
    .Name("myTree")
    .AllowCheckBoxes(true)
    .PopulateChildrenOnCheck(true)
    .Async("GetChildrenAsync")
)
public static MvcHtmlString MyTreeView(this HtmlHelper html, params...){
    var myHtmlContent = ....;
    // .. implement your functionality and generate the html to put in your view
    return MvcHtmlString.Create(myHtmlContent);
}
<div>@Html.MyTreeView(params...)</div>
请注意,您可以将一些选项传递给它。 此外,我希望能够通过异步传递将填充我的TreeView的操作的名称。因此,如果我在mysite/myController/indexAction中使用这个组件,我希望传递一个将填充我的组件的操作的名称。让我们举例说明。我想要这样的东西:

@(Html.Kendo().MaskedTextBox()
    .Name("phone_number")
    .Mask("(999) 000-0000")
    .Value("555 123 4567")
)
@(Html.Foo().HierarchyView()
    .Name("myTree")
    .AllowCheckBoxes(true)
    .PopulateChildrenOnCheck(true)
    .Async("GetChildrenAsync")
)
public static MvcHtmlString MyTreeView(this HtmlHelper html, params...){
    var myHtmlContent = ....;
    // .. implement your functionality and generate the html to put in your view
    return MvcHtmlString.Create(myHtmlContent);
}
<div>@Html.MyTreeView(params...)</div>
因此,我可以在myController上实现一个操作

string GetChildrenAsync(int idKey) {
    var nodes = new List<HierarchViewNodes>();
    (...) //implementation to populate the children nodes
    return JsonConvert.SerializeObject(nodes);
}
字符串GetChildrenAsync(int-idKey){
var节点=新列表();
(…)//填充子节点的实现
返回JsonConvert.SerializeObject(节点);
}
因此,这将是我的自定义控件的一个开始。当然,我可以扩展很多。 我已经搜索并学习了RenderPartial和RenderAction,但我还不知道如何充分利用它来制作我解释过的真正可重用的控件。 有没有人开发了这样的东西,可以给我一个跳转开始,或文章链接,或任何东西?我搜索了很多,但没有找到任何关于如何控制这样一个控件的信息


提前谢谢

您可能想看看制作一些。例如,您的可能如下所示:

@(Html.Kendo().MaskedTextBox()
    .Name("phone_number")
    .Mask("(999) 000-0000")
    .Value("555 123 4567")
)
@(Html.Foo().HierarchyView()
    .Name("myTree")
    .AllowCheckBoxes(true)
    .PopulateChildrenOnCheck(true)
    .Async("GetChildrenAsync")
)
public static MvcHtmlString MyTreeView(this HtmlHelper html, params...){
    var myHtmlContent = ....;
    // .. implement your functionality and generate the html to put in your view
    return MvcHtmlString.Create(myHtmlContent);
}
<div>@Html.MyTreeView(params...)</div>
您可以在Razor视图中使用它,如下所示:

@(Html.Kendo().MaskedTextBox()
    .Name("phone_number")
    .Mask("(999) 000-0000")
    .Value("555 123 4567")
)
@(Html.Foo().HierarchyView()
    .Name("myTree")
    .AllowCheckBoxes(true)
    .PopulateChildrenOnCheck(true)
    .Async("GetChildrenAsync")
)
public static MvcHtmlString MyTreeView(this HtmlHelper html, params...){
    var myHtmlContent = ....;
    // .. implement your functionality and generate the html to put in your view
    return MvcHtmlString.Create(myHtmlContent);
}
<div>@Html.MyTreeView(params...)</div>
@Html.MyTreeView(参数…)

这是一个非常简单的例子,但希望它能让您走上正确的道路。

您可能想看看如何制作一些。例如,您的可能如下所示:

@(Html.Kendo().MaskedTextBox()
    .Name("phone_number")
    .Mask("(999) 000-0000")
    .Value("555 123 4567")
)
@(Html.Foo().HierarchyView()
    .Name("myTree")
    .AllowCheckBoxes(true)
    .PopulateChildrenOnCheck(true)
    .Async("GetChildrenAsync")
)
public static MvcHtmlString MyTreeView(this HtmlHelper html, params...){
    var myHtmlContent = ....;
    // .. implement your functionality and generate the html to put in your view
    return MvcHtmlString.Create(myHtmlContent);
}
<div>@Html.MyTreeView(params...)</div>
您可以在Razor视图中使用它,如下所示:

@(Html.Kendo().MaskedTextBox()
    .Name("phone_number")
    .Mask("(999) 000-0000")
    .Value("555 123 4567")
)
@(Html.Foo().HierarchyView()
    .Name("myTree")
    .AllowCheckBoxes(true)
    .PopulateChildrenOnCheck(true)
    .Async("GetChildrenAsync")
)
public static MvcHtmlString MyTreeView(this HtmlHelper html, params...){
    var myHtmlContent = ....;
    // .. implement your functionality and generate the html to put in your view
    return MvcHtmlString.Create(myHtmlContent);
}
<div>@Html.MyTreeView(params...)</div>
@Html.MyTreeView(参数…)

这是一个非常简单的示例,但希望它能让您走上正轨。

我建议使用一些HTML扩展,如rwisch45所述,但在单独的“子助手”中进行保护(和组织),如Kendo和DevXPress:

public static class HtmlExtensions
{
   public static static MyCustomHelper CustomHelper(this HtmlHelper htmlHelper)
   {
      return new MyCustomHelper(htmlHelper);
   }
}

public class MyCustomHelper
{
   HtmlHelper _HtmlHelper;
   public MyCustomHelper(HtmlHelper htmlHelper) { _HtmlHelper = htmlHelper; }

   public MvcHtmlString WriteSomethingInteresting(string value)
   { return new MvcHtmlString(value); }

   public MyCustomGrid CreateMyGrid(object gridOptions)
   {
      // I won't show now how to transform dynamic into type.
      // You can find that on SO quite easy.
      var typedOptions = TransformDynamicIntoClass<GridOptions>(gridOptions);

      return new MyCustomGrid(typedOptions);
   }
}

public class MyCustomGrid : IHtmlString
{
   public string ToHtmlString()
   {
      // Return your grid as an HTML object!
   }
}
但是,您可以稍微使用IDisposable,以获得如下功能:

@using(Html.CustomHelper().MyCustomGrid(....))
{
   // Dunno what could come here for a grid (poor sample) but maybe for a pane helper?
}

我建议使用一些HTML扩展,如rwisch45所说,但在单独的“子助手”中进行保护(和组织),如Kendo和DevExpress:

public static class HtmlExtensions
{
   public static static MyCustomHelper CustomHelper(this HtmlHelper htmlHelper)
   {
      return new MyCustomHelper(htmlHelper);
   }
}

public class MyCustomHelper
{
   HtmlHelper _HtmlHelper;
   public MyCustomHelper(HtmlHelper htmlHelper) { _HtmlHelper = htmlHelper; }

   public MvcHtmlString WriteSomethingInteresting(string value)
   { return new MvcHtmlString(value); }

   public MyCustomGrid CreateMyGrid(object gridOptions)
   {
      // I won't show now how to transform dynamic into type.
      // You can find that on SO quite easy.
      var typedOptions = TransformDynamicIntoClass<GridOptions>(gridOptions);

      return new MyCustomGrid(typedOptions);
   }
}

public class MyCustomGrid : IHtmlString
{
   public string ToHtmlString()
   {
      // Return your grid as an HTML object!
   }
}
但是,您可以稍微使用IDisposable,以获得如下功能:

@using(Html.CustomHelper().MyCustomGrid(....))
{
   // Dunno what could come here for a grid (poor sample) but maybe for a pane helper?
}

嗨,阿尔玛,我在尝试你的方法。我认为框架上不存在接口IMvcHtmlString。我正在尝试实现接口IHtmlSting。你认为它会起作用吗?它不能很好地呈现我的脚本。我不知道这是否是因为我必须返回一个MVCHTMLString而不是纯字符串(从IHtmlString接口重写htmlsting方法就可以了)。你知道我可能做错了什么吗?对不起,是打字错误。这是
IHtmlString
。更新了我的答案。“不工作”是指结果文本按原样呈现而不是有效的HTML元素吗?因为它以纯字符串的形式返回,如果我遇到如下情况:我有一个访问错误:不允许加载本地资源。我认为这是一个安全问题。在视图中放置完全相同的调用(例如:
src='path.js'
)可以正常工作?是的,将其放置在视图中可以使事情正常工作。因此,我可以选择2个选项:1)使用此帮助器时,请明确,必须在调用用户控件的视图中引用某些.js和.css,或者2)研究并实现一种方法,该方法将允许在用户控件中引用脚本或样式,而不会出现不允许出现的问题。我会做一些研究,让你知道我在这里采取的方法。嗨@ALMMa,我正在尝试你的方法。我认为框架上不存在接口IMvcHtmlString。我正在尝试实现接口IHtmlSting。你认为它会起作用吗?它不能很好地呈现我的脚本。我不知道这是否是因为我必须返回一个MVCHTMLString而不是纯字符串(从IHtmlString接口重写htmlsting方法就可以了)。你知道我可能做错了什么吗?对不起,是打字错误。这是
IHtmlString
。更新了我的答案。“不工作”是指结果文本按原样呈现而不是有效的HTML元素吗?因为它以纯字符串的形式返回,如果我遇到如下情况:我有一个访问错误:不允许加载本地资源。我认为这是一个安全问题。在视图中放置完全相同的调用(例如:
src='path.js'
)可以正常工作?是的,将其放置在视图中可以使事情正常工作。因此,我可以选择2个选项:1)使用此帮助器时,请明确,必须在调用用户控件的视图中引用某些.js和.css,或者2)研究并实现一种方法,该方法将允许在用户控件中引用脚本或样式,而不会出现不允许出现的问题。我会做一些研究,让你知道我在这里采取的方法。谢谢你。事实上,定制的HTMLHelper可能是最好的方法。我正在实现它,但我正在使用@ALMMa answer,因为我想创建一个类似于自定义组件库的东西,他的方法将使事情更有条理。谢谢你的回答!谢谢你。事实上,定制的HTMLHelper可能是最好的方法。我正在实现它,但我正在使用@ALMMa answer,因为我想创建一个类似于自定义组件库的东西,他的方法将使事情更有条理。谢谢你的回答!