mmilic,继自你的回应 to my 先前的想法..
不需要额外的逻辑!这就是重点,您对相关类不执行任何操作,只是将它们包装在一些实例化气泡包装中! :)
好的,我本来只是要点,但我想亲眼看看这项工作,所以我拼凑了一些very代码很粗糙,但概念已经存在并且似乎有效。
为长篇文章道歉
安全加载器
这基本上就是我提到的“气泡”。它将获取控件 HTML,捕获渲染期间发生的任何错误。
public class SafeLoader
{
public static string LoadControl(Control ctl)
{
// In terms of what we could do here, its down
// to you, I will just return some basic HTML saying
// I screwed up.
try
{
// Get the Controls HTML (which may throw)
// And store it in our own writer away from the
// actual Live page.
StringWriter writer = new StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
ctl.RenderControl(htmlWriter);
return writer.GetStringBuilder().ToString();
}
catch (Exception)
{
string ctlType = ctl.GetType().Name;
return "<span style=\"color: red; font-weight:bold; font-size: smaller;\">" +
"Rob + Controls = FAIL (" +
ctlType + " rendering failed) Sad face :(</span>";
}
}
}
和一些控件..
好吧,我只是在这里模拟了两个控件,一个会抛出垃圾,另一个会渲染垃圾。说到这里,我才不管呢。这些将替换为您的自定义控件。
坏控制
public class BadControl : WebControl
{
protected override void Render(HtmlTextWriter writer)
{
throw new ApplicationException("Rob can't program controls");
}
}
良好的控制
public class GoodControl : WebControl
{
protected override void Render(HtmlTextWriter writer)
{
writer.Write("<b>Holy crap this control works</b>");
}
}
The Page
好的,让我们看看“测试”页面。这里我只是实例化控件,抓取它们的 html 并输出它,我将遵循对设计器支持等的想法。
页面代码隐藏
protected void Page_Load(object sender, EventArgs e)
{
// Create some controls (BadControl will throw)
string goodHtml = SafeLoader.LoadControl(new BadControl());
Response.Write(goodHtml);
string badHtml = SafeLoader.LoadControl(new GoodControl());
Response.Write(badHtml);
}
Thoughts
好吧,我知道你在想什么,“这些控件是以编程方式实例化的,那么设计师支持呢?我花了很多时间让这些控件对设计师来说很好,现在你却在扰乱我的魔力”。
好的,所以我还没有真正测试过这个(可能一分钟就能完成!)但这里的想法是重写页面的 CreateChildControls 方法,并获取表单上添加的每个控件的实例并通过 SafeLoader 运行它。如果代码通过,您可以将其正常添加到 Controls 集合中,如果没有,那么您可以创建错误的文字或其他内容,这取决于您,我的朋友。
最后..
再次,很抱歉这篇文章很长,但我想在这里获取代码,以便我们可以讨论这个:)
我希望这有助于展示我的想法:)
Update
通过在设计器中添加一个控件并用它覆盖 CreateChildControls 方法进行了测试,工作正常,可能需要一些清理以使事情看起来更好,但我将把它留给你;)
protected override void CreateChildControls()
{
// Pass each control through the Loader to check
// its not lame
foreach (Control ctl in Controls)
{
string s = SafeLoader.LoadControl(ctl);
// If its bad, smack it downnnn!
if (s == string.Empty)
{
ctl.Visible = false; // Prevent Rendering
string ctlType = ctl.GetType().Name;
Response.Write("<b>Problem Occurred Rendering " +
ctlType + " '" + ctl.ID + "'.</b>");
}
}
}
Enjoy!