A Generic ViewManager Helper Class

 Hi All,

 Following on from something I saw from Scott Guthrie, a ViewManager which allows you to render a usercontrol and return the generated HTML. I decided to implement a more generic approach which allowed you to set any properties of your custom usercontrol and then render it. So you would use it like so:

//Init the viewmanager
ViewManager<WebUserControl1> man = new ViewManager<WebUserControl1>("~/WebUserControl1.ascx");

We now have access to the control the manager is rendering through the Control property and can set its properties directly like so:

man.Control.Name = "bob";
man.Control.AnotherProperty = "test";


Then finally you call the render method on you viewmanager to get the generated HTML:

Response.Write(man.Render());



Basically the same thing that Scott has done but a little more generic and allows you to set any property of the control you need to render. The code for the ViewManager is below:

public class ViewManager<T> where T : Control {

        #region Properties

        private T _control = default(T);

        /// <summary>
        /// Gives you access to the control you are rendering allows
        /// you to set custom properties etc.
        /// </summary>
        public T Control {
            get {
                return _control;
            }
        }

        // Used as a placeholder page to render the control on.
        private Page _holder = null;

        #endregion    

        #region Constructor

        /// <summary>
        /// Default constructor for this view manager, pass in the path for the control
        /// that this view manager is render.
        /// </summary>
        /// <param name="inPath"></param>
        public ViewManager(string inPath) {
            //Init the holder page
            _holder = new Page();

            // Create an instance of our control
            _control = (T)_holder.LoadControl(inPath);

            // Add it to our holder page.
            _holder.Controls.Add(_control);
        }

        #endregion

        #region Rendering

        /// <summary>
        /// Renders the current control.
        /// </summary>
        /// <returns></returns>
        public string Render() {           
            StringWriter sw = new StringWriter();

            // Execute the page capturing the output in the stringwriter.
            HttpContext.Current.Server.Execute(_holder, sw, false);

            // Return the output.
            return sw.ToString();
        }

        #endregion

    }




Thanks
Stefan


 

Published Monday, March 10, 2008 12:53 PM by stefan.sedich

Comments

# re: A Generic ViewManager Helper Class

Monday, March 10, 2008 12:05 AM by Blair Davidson

You should have said im a legend in your post stef :)

# re: A Generic ViewManager Helper Class

Monday, March 10, 2008 12:06 AM by stefan.sedich

Sorry mate forgot that one :P

# re: A Generic ViewManager Helper Class

Wednesday, June 18, 2008 6:39 AM by Ghanshyam Lohar

Here is one more approach which I had to modify since in my case the controls were not derived from UserControl but from WebControl.

public class ViewManager

   {

       public static string RenderView(string path)

       {

           return RenderView(path, null);

       }

       private static string RenderView(Page pageHolder, Control viewControl, object data)

       {

           if (data != null)

           {

               Type viewControlType = viewControl.GetType();

               FieldInfo field = viewControlType.GetField("Data");

               if (field != null)

               {

                   field.SetValue(viewControl, data);

               }

               else

               {

                   throw new Exception("View file: " + viewControl.ToString() + " does not have a public Data property");

               }

           }

           pageHolder.Controls.Add(viewControl);

           StringWriter output = new StringWriter();

           HttpContext.Current.Server.Execute(pageHolder, output, false);

           return output.ToString();

       }

       public static string RenderView(Type type, object data)

       {

           Page pageHolder = new Page();

           Control viewControl = pageHolder.LoadControl(type, null);

           return RenderView(pageHolder, viewControl, data);

       }

       public static string RenderView(string path, object data)

       {

           Page pageHolder = new Page();

           Control viewControl = pageHolder.LoadControl(path);

           return RenderView(pageHolder, viewControl, data);

       }

   }

and access it as:

       Type type = typeof(CommunityServer.Controls.DisplayUserWelcome);

       return ViewManager.RenderView(type, null);

Hope this helps someone.

Ghanshyam

# re: A Generic ViewManager Helper Class

Wednesday, June 18, 2008 6:47 AM by Ghanshyam Lohar

Here is one more approach which I had to modify since in my case the controls were not derived from UserControl but from WebControl.

public class ViewManager

   {

       public static string RenderView(string path)

       {

           return RenderView(path, null);

       }

       private static string RenderView(Page pageHolder, Control viewControl, object data)

       {

           if (data != null)

           {

               Type viewControlType = viewControl.GetType();

               FieldInfo field = viewControlType.GetField("Data");

               if (field != null)

               {

                   field.SetValue(viewControl, data);

               }

               else

               {

                   throw new Exception("View file: " + viewControl.ToString() + " does not have a public Data property");

               }

           }

           pageHolder.Controls.Add(viewControl);

           StringWriter output = new StringWriter();

           HttpContext.Current.Server.Execute(pageHolder, output, false);

           return output.ToString();

       }

       public static string RenderView(Type type, object data)

       {

           Page pageHolder = new Page();

           Control viewControl = pageHolder.LoadControl(type, null);

           return RenderView(pageHolder, viewControl, data);

       }

       public static string RenderView(string path, object data)

       {

           Page pageHolder = new Page();

           Control viewControl = pageHolder.LoadControl(path);

           return RenderView(pageHolder, viewControl, data);

       }

   }

and access it as:

       Type type = typeof(CommunityServer.Controls.DisplayUserWelcome);

       return ViewManager.RenderView(type, null);

Hope this helps someone.

Ghanshyam

# re: A Generic ViewManager Helper Class

Thursday, November 27, 2008 2:32 PM by Andres Larrimbe

Inside the UserControl I have a RadChart telerik control and that is causing the RenderView function to throw an error, has anyone face a similar challenge? Can someone please give me a hand here.