我做了一个web自定义控件,它由一个存放在站点某目录下的xml文件提供数据,控件有个属性xmlurl就指向这个xml文件的相对路径。现在,控件已开发完毕。美中不足的就是,这个控件只能支持运行时,不具备对设计时的支持。即,在浏览器上显示正常,但在 Visual Studio .NET 2003 的web窗体编辑环境里只能显示出一个毫无生气的傻呆呆的普通控件模样的标签:[WebControlLibrary1 "WebControlLibrary12"],不是我追求的所见即所得的形象。其实,如果在将空间从工具箱拖入页面时,如果控件能够立即自动获取到站点的物理路径,那就完全有办法在默认位置找到它所需的xml文件,然后通过Render在设计界面显示出自己的模样。
一下是我模拟的一个样板程序
Imports System.ComponentModel
Imports System.Web.UI
Imports System.IO
Imports System.Web.Configuration.HttpConfigurationContext
Imports System.DirectoryServices
<DefaultProperty("Text"), ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")> Public Class WebCustomControl1
    Inherits System.Web.UI.WebControls.WebControl
    Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
        output.Write(这里是需要大家帮助我填写的代码)
    End Sub
End Class我的要求就是,当把WebCustomControl1控件从工具箱拖到web窗体时,我看到的应该是站点的物理路径或者是bin的物理路径,或者是页面所处的物理路径。
一下代码是我试过的都满足不了要求1、output.Write(Me.TemplateSourceDirectory)
2、Dim ap As System.Windows.Forms.Application
        output.Write(ap.StartupPath()
3、output.Write(ResolveUrl("~"))
4、output.Write(Directory.GetCurrentDirectory)等等
都无法实现将自定义控件由工具箱拖入页面设计器的同时,控件自己就立即能获取所处站点物理路径的目的。其中GetCurrentDirectory在特定情况下可以返回bin目录的位置,有时是C:\WINNT\system32,有时则是当前正在活动的文件夹目录,没个diao准,但对控件引用方式有特殊要求,使用起来不方便。请大家集思广益,把这个问题解决了。这个问题很重要,可以设计更为复杂和人性化的自定义控件,使控件在设计器中自动找到自己所需的默认的数据文件而不需要使用者专门在属性窗中为其指定。可以设计出所见即所得的web控件
       

解决方案 »

  1.   

    follow the example below:ControlDesigner - Accessing Web.Config at Design Time
    http://blogs.msdn.com/mszcool/archive/2004/06/30/169793.aspx
      

  2.   

    不错!添加 com 引用 “Microsoft Development Environment 7.0“获取项目的绝对路径 测试过 在不同的项目里都能得到正确的物理路径
    public class TestControlDesigner : System.Web.UI.Design.ControlDesigner
    {
    public override string GetDesignTimeHtml()
    {
    string html = "found nothing";
    try 
    {
    EnvDTE.DTE devenv = null;
    devenv = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1");
    Array projects = (System.Array)devenv.ActiveSolutionProjects;
    if((projects.Length == 0) || (projects.Length > 1))
    {
    html = "Exactly one project must be active";

    else 
    {
    EnvDTE.Project project = (EnvDTE.Project)(projects.GetValue(0));
    System.IO.FileInfo info = new System.IO.FileInfo(project.FullName);
                        html=info.Directory.FullName;
    }

    catch(Exception ex) 
    {
    html = "Exception occured: " + ex.Message;
    }
    return html;
    }
      

  3.   

    测试控件[DefaultProperty("Text"),
    ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]
        [Designer("TestControlDesigner")]
    public class WebCustomControl1 : System.Web.UI.WebControls.WebControl
    {
    private string text; [Bindable(true),
    Category("Appearance"),
    DefaultValue("")]
    public string Text
    {
    get
    {
    return text;
    } set
    {
    text = value;
    }
    } /// <summary>
    /// 将此控件呈现给指定的输出参数。
    /// </summary>
    /// <param name="output"> 要写出到的 HTML 编写器 </param>
    protected override void Render(HtmlTextWriter output)
    {
    output.Write(Text);
    }
    }
      

  4.   

    我英文不好,思归给的办法相信有用,但我还需要啃一会儿。
     xinyulou(心雨楼 - ︻┹一) 的办法,我马上试了,果然适用,只是Interop.EnvDTE.dll要占用236k的站点空间,没关系,发布前删去就可以了,反正Interop.EnvDTE.dll只是在设计期用到。
    千金散去还复来,很高兴得到二位高手相助。多谢,散分。
      

  5.   

    看来思归给的http://blogs.msdn.com/mszcool/archive/2004/06/30/169793.aspx用的也是Interop.EnvDTE.dll。惭愧,我竟然从来就未翻看过DTE 对象的有关文档。