为字符属性定义选项[web自定义控件]

当我们定义一个enum属性时,通过IDE的属性页能看到一个下拉的列表。能不能为一个字符属性也定义一个下拉列表呢?实现也不是很复杂,需要定义一个TypeConverter,看下面代码
public class MyStrTypeConverter : TypeConverter
{
    
public MyStrTypeConverter (){
    }


    
private TypeConverter.StandardValuesCollection values;
 
    
public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) {
        
if (this.values == null)
        
{
            MyStrConfigurations conf 
= MyStrConfigurations.GetConfig();
            
string[] arr = new string[conf.Names.Length];
            
for (int i = 0; i < arr.Length; i++)
                arr[i] 
= conf.Names[i];

            
this.values = new TypeConverter.StandardValuesCollection(arr);
        }

        
return this.values;

    }

    
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) {
        
return true;
    }


    
public override bool GetStandardValuesSupported(ITypeDescriptorContext context) {
        
return true;
    }

    
public override bool IsValid(ITypeDescriptorContext context, object value) {
        
if (value is string)
        
{
            
string str = (string)value;
            MyStrConfigurations conf 
= MyStrConfigurations.GetConfig();
            
            
for (int i = 0; i < conf.AdTypes.Length; i++)
            
{
                
if (conf.Names[i] == str)
                    
return true;
            }

        }

        
return false;
    }

}


上面的MyStrConfigurations是一个管理这个字符列表的类,主要使用其属性数组Names。先不管这个,看一下如何使用该类
private string mStrAdType;
[TypeConverter(
typeof(MyStrTypeConverter))]
public string AdStrType{
    
get{return this.mStrAdType;}
    
set{this.mStrAdType = value;}
}

关键是定义属性的TypeConverter(typeof(MyStrTypeConverter))

过程就是上面的两步就可以了。

上面所说的MyStrConfigurations,我给他的任务是两个
1.添加默认的配置文件(Mystrings.xml)到网站的App_Data目录下。我原指望web.config,发现设计时读取几乎不可能。干脆自己定义一个配置文件。
2.读取网站app_data目录下的Mystrings.xml构造属性下拉列表。


读取项目所在目录,一般都使用下面的代码,代码思路是取项目被选中的项。注意当前打开的文件可能不是当前被选中的项
string path = "";
EnvDTE.DTE devenv 
= (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.8.0");//vs2005. vs2003应是VisualStudio.DTE.7.1
Array projects = (System.Array)devenv.ActiveSolutionProjects;
if ((projects.Length == 0|| (projects.Length > 1))
{
    
//path = "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);
    path 
= info.Directory.FullName;
}


解决方案一般有几个项目,如果之前打开了一个设计的aspx,偶尔又选择并打开其他项目下的文件编辑,回到前面的aspx编辑时当前活动的文本对象就不是当前选中的项,路径就错了。能否取得当前活动文档对象的项目呢?通过宏编辑器尝试了不少的方法,结果发现以下代码简单可靠。是否有什么不足呢?
string path = "";
EnvDTE.DTE devenv 
= (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.8.0");
System.IO.FileInfo info 
= new System.IO.FileInfo(devenv.ActiveDocument.ProjectItem.ContainingProject.FullName);
path 
= info.Directory.FullName;

如何向站点输出默认的配置xml文件呢?

首先编辑默认的xml作为“嵌入的资源”作为控件库项目的一项内容发布
最后就是控件读取自身资源输出到项目指定目录下。以下是读取输出的一段代码,参考自http://www.codeproject.com/KB/custom-controls/MP3PlayerControl.aspx

/// <summary>
/// Writes Flash File from assembly resources
/// </summary>
/// <param name="FilePath">Directory Path to flash file</param>
/// <param name="FileName">Flash file name</param>
/// <param name="AssemblyReference">Reference to assembly with resource file</param>
/// <param name="ResourceName">Name of resource to write to file</param>
/// <param name="OverWrite">Whether method should overwrite existing file if detected</param>

private static void FileFromResource(string FilePath, string FileName, Assembly AssemblyReference, string ResourceName, bool OverWrite)
{
    
//Only write file if it's not already there
    if (!File.Exists(FilePath + FileName) || OverWrite)
    
{
        
//Create Destination Directory if not in existence
        DirectoryInfo DirInfo = new DirectoryInfo(FilePath);
        
if (!DirInfo.Exists)
        
{
            Directory.CreateDirectory(FilePath);
        }

        
//Create Stream from Resource in Assembly
        Stream InputStream = AssemblyReference.GetManifestResourceStream(ResourceName);
        BinaryReader Reader 
= new BinaryReader(InputStream);
        FileStream OutputStream 
= new FileStream(FilePath + FileName, FileMode.Create);
        BinaryWriter Writer 
= new BinaryWriter(OutputStream);
        
//Read through stream and write to file
        bool LoopRead = true;
        
try
        
{
            
while (LoopRead)
            
{
                
byte NextByte = Reader.ReadByte();
                
if (Convert.ToInt32(NextByte) == -1)
                
{
                    LoopRead 
= false;
                }

                OutputStream.WriteByte(NextByte);
            }

        }

        
catch
        
{
            
//Catch exception when end of stream is reached and close all streams
            InputStream.Close();
            OutputStream.Close();
            Reader.Close();
            Writer.Close();
        }

    }

}


使用的方法, MyStrConfigurations类的静态方法GetConfig
public static MyStrConfigurations GetConfig()
{           
    
string strProPath = getProjectPath();
    
string strPath = string.Format("{0}\\App_Data\\MyStrings.xml", strProPath);
    
//检查文件是否存在,不存在时读取dll中的资源文件输出
    System.IO.FileInfo info = new FileInfo(strPath);
    
if (!info.Exists)
    
{
        
if (!info.Directory.Exists)
            info.Directory.Create();
        Assembly assemblyReference 
= Assembly.GetExecutingAssembly();
        FileFromResource(strProPath 
+ "\\App_Data\\""MyStrings.xml", assemblyReference, "Kvn.Web.UI.Controls.MyStrings.xml"true);
    }

    
//通过xml反序化为配置对象
    object obj = null;
    System.IO.StreamReader read 
= null;            
    
try
    
{
        read 
= new System.IO.StreamReader(strPath);
        
//读取字符串
        XmlSerializer ser = new XmlSerializer(typeof(MyStrConfigurations));
        obj 
= ser.Deserialize(read);
    }

    
catch (Exception ee)
    
{
        
throw ee;
    }

    
finally
    
{
        
if(read!=null)
        read.Close();
    }


    MyStrConfigurations cf
= (MyStrConfigurations)obj;
    cf.WorkProject 
= strProPath;
    
return cf;
}

posted @ 2008-07-09 16:20  生命体验之kevin-Y  阅读(744)  评论(0编辑  收藏  举报