strongwind
strongwind

Reputation: 131

In MVC, How can I develop something like the old school User Control?

I have a TreeView, wish is used to display some hierarchy. Also, I have some behaviors implemented, such as if the collapsed nodes will be opened when the parent is checked, or if it's lazy loading or will load everything automatically. But I don't want to let these behaviors hard coded. I want to create a customizable control. Something like Telerik Kendo UI does. They have a control developed, that can be used like this:

@(Html.Kendo().MaskedTextBox()
    .Name("phone_number")
    .Mask("(999) 000-0000")
    .Value("555 123 4567")
)

Notice that you can pass some options to it. Also, I want to be able to pass the name of the action that will populate my TreeView using async. So, if I use this component at, for example, mysite/myController/indexAction, I want to pass a name of the action who will populate my component asynchronous. Let's exemplify. I want something like this:

@(Html.Foo().HierarchyView()
    .Name("myTree")
    .AllowCheckBoxes(true)
    .PopulateChildrenOnCheck(true)
    .Async("GetChildrenAsync")
)

So, I can implement at myController an action

string GetChildrenAsync(int idKey) {
    var nodes = new List<HierarchViewNodes>();
    (...) //implementation to populate the children nodes
    return JsonConvert.SerializeObject(nodes);
}

So, it would be an start for my customizable control. Of course I can extend it a lot. I've searched and learned about RenderPartial and RenderAction, but I can't figure out yet how I can fully use it to make really reusable controls like the one I explained.

Upvotes: 1

Views: 174

Answers (2)

Anderson Matos
Anderson Matos

Reputation: 3147

I'd suggest some HTML extensions, as rwisch45 said, but protected (and organized) within a separate "sub-helper", like Kendo and 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!
   }
}

This way you'll have:

@Html.CustomHelper().MyCustomGrid(new { Option1 = "", Option2 = "", ...... });

You may, however, play a little with IDisposable, to have something like:

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

Upvotes: 2

rwisch45
rwisch45

Reputation: 3702

You might want to take a look at making some custom HTML helpers. For example, yours might look something like this:

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);
}

and you could use it in your Razor view like this:

<div>@Html.MyTreeView(params...)</div>

That is a very simple example, but hopefully it puts you on the right track.

Upvotes: 2

Related Questions