我正在动态加载用户控件,将它们添加到Web表单的Controls集合中.
我想隐藏用户控件,如果它们在渲染时导致未处理的异常.
所以,我尝试连接到每个UserControl的Error事件,但似乎这个事件永远不会像为Page类那样触发UserControls.
做了一些谷歌搜索,似乎并不乐观.这里有什么想法?
mmilic,继续你对我之前的想法的回应 ..
无需额外的逻辑!这就是重点,你对所讨论的类没有任何作用,只是将它们包装在一些实例化的bubble-wrap中!:)
好吧,我本来只是要点,但我想看到这个工作对我自己,所以我拼凑了一些非常粗糙的代码,但概念是存在的,它似乎工作.
长篇大论
这基本上就是我提到的"泡沫"..它将获取控件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 "" +
"Rob + Controls = FAIL (" +
ctlType + " rendering failed) Sad face :(";
}
}
}
好吧,我只是在这里嘲笑两个控件,一个将抛出另一个将渲染垃圾.点这里,我不给废话.这些将被您的自定义控件替换..
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("Holy crap this control works"); } }
好吧,让我们看看"测试"页面.在这里,我只是实例化控件,抓取他们的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); }
好吧,我知道你在想什么,"这些控件是以编程方式实例化的,设计师支持怎么样?我花了几个小时让这些控件对设计师很好,现在你正在弄乱我的魔力".
好吧,所以我还没有真正测试过这个(可能会在一分钟内完成!)但这里的想法是覆盖页面的CreateChildControls方法,并在表单上添加每个控件的实例并通过SafeLoader运行它.如果代码通过,您可以照常将它添加到Controls集合中,否则,您可以创建错误的文字或其他内容,由我的朋友决定.
再次,对于长篇文章感到抱歉,但我想在这里获取代码,以便我们可以讨论这个:)我希望这有助于证明我的想法:)
通过在设计器上放置一个控件并使用它来覆盖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("Problem Occurred Rendering " + ctlType + " '" + ctl.ID + "'."); } } }
请享用!