Created
April 7, 2010 03:01
-
-
Save hugoware/358458 to your computer and use it in GitHub Desktop.
Uses WebControls to allow content to be written to multiple areas on the same view using ASP.NET MVC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Web; | |
using System.Web.UI; | |
namespace MvcWebControls { | |
/// <summary> | |
/// Creates a zone that writes content to the matching ContentArea | |
/// </summary> | |
public class ContentArea : TemplateControl { | |
#region Constants | |
private const string CONTENT_AREA_CONTAINER = "AreaContainers"; | |
#endregion | |
#region Constructors | |
/// <summary> | |
/// Creates a new ContentArea that allows you to write content to ContentDisplayAreas | |
/// </summary> | |
public ContentArea() { | |
ContentArea._Areas.Add(this); | |
} | |
#endregion | |
#region Properties | |
/// <summary> | |
/// The name of the content marker to write content to | |
/// </summary> | |
public string Target { get; set; } | |
#endregion | |
#region Shared Information | |
//returns a list of content areas for the page | |
internal static List<ContentArea> _Areas { | |
get { | |
//attempt to find the container and create a | |
//new one if it hasn't been found yet | |
List<ContentArea> containers = | |
HttpContext.Current.Items[CONTENT_AREA_CONTAINER] as List<ContentArea>; | |
if (containers == null) { | |
containers = new List<ContentArea>(); | |
HttpContext.Current.Items[CONTENT_AREA_CONTAINER] = containers; | |
} | |
//return the generated container | |
return containers; | |
} | |
} | |
//gets the content for this control | |
internal LiteralControl _GetContent() { | |
//write the content to a string | |
using (StringWriter output = new StringWriter()) { | |
using (_ContentAreaWriter html = new _ContentAreaWriter(output)) { | |
//write the content | |
base.Render(html); | |
//create the content and return it as a control | |
string content = output.ToString(); | |
return new LiteralControl(content); | |
} | |
} | |
} | |
#endregion | |
#region Handling Events | |
//do not render these areas | |
protected override void Render(HtmlTextWriter writer) { | |
if (!(writer is _ContentAreaWriter)) { return; } | |
base.Render(writer); | |
//don't actually ever render this to | |
//the real HTML writer | |
//base.Render(writer); | |
} | |
#endregion | |
#region Helper Classes | |
private class _ContentAreaWriter : HtmlTextWriter { | |
public _ContentAreaWriter(TextWriter writer) : base(writer) { } | |
} | |
#endregion | |
} | |
/// <summary> | |
/// Consumes content written into markers | |
/// </summary> | |
[ParseChildren(true)] | |
[PersistChildren(false)] | |
public class ContentDisplayArea : Control { | |
#region Properties | |
/// <summary> | |
/// Should this accepts any targets even if the case of | |
/// the names do not match | |
/// </summary> | |
public bool IgnoreCase { get; set; } | |
/// <summary> | |
/// Ignores ContentAreas that have matching IDs | |
/// </summary> | |
public bool IgnoreDuplicates { get; set; } | |
#endregion | |
#region Constructors | |
/// <summary> | |
/// Creates a new area to write content to | |
/// </summary> | |
public ContentDisplayArea() { | |
} | |
#endregion | |
#region Handling Events | |
//handles finding the correct areas to render | |
protected override void Render(HtmlTextWriter writer) { | |
this.ID = this.ID ?? string.Empty; | |
//get the correct way to handle case | |
StringComparison compare = this.IgnoreCase | |
? StringComparison.OrdinalIgnoreCase | |
: StringComparison.Ordinal; | |
//get a list of IDs to track | |
List<string> added = new List<string>(); | |
//add all of the controls that exist for this page | |
foreach (ContentArea area in ContentArea._Areas) { | |
if (!this.ID.Equals(area.Target, compare)) { continue; } | |
//check the IDs for duplicates | |
if (this.IgnoreDuplicates && | |
!string.IsNullOrEmpty(area.ID) && | |
added.Any(item => item.Equals(area.ID, compare))) { | |
continue; | |
} | |
//add the ID of the items checked | |
if (area.ID is string) { | |
added.Add(area.ID ?? string.Empty); | |
} | |
//add each of the child controls | |
this.Controls.Add(area._GetContent()); | |
//No need to hide controls since ContentAreas | |
//aren't actually ever rendered | |
//area.Controls.Clear(); | |
} | |
//finally, render the control normally | |
base.Render(writer); | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment