老田的专栏

把我知道的奉献给你,你明白的也请告诉我

用户操作
[即时聊天] [发私信] [加为好友]
老田ID:RonoTian
27495次访问,排名4478(-2),好友144人,关注者139人。
最好看电视,看书,广告也不想放过,不过看着int,for,while等这些东西最顺眼。
RonoTian的文章
原创 19 篇
翻译 0 篇
转载 3 篇
评论 174 篇
老田的公告
这些文章欢迎引用或者转载,但是请注明来源:http://blog.csdn.net/RonoTian
最近评论
tianjiao85:不知道你的是否好,但是可以学到东西。
CleverKingWM:<sdfsdf></sdfsdf>
heku518:dimArray[i + 1, k] = datagridview.Rows[i].Cells[j].Value.ToString();
未将对象引用设置到对象的实例。
arren_zhan:不错 正想写这方面的功能
roc196:恩,确实不错,呵呵~~
文章分类
收藏
    相册
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 在C#应用中,设计自己的配置文件收藏

    新一篇: C#基础系列:实现自己的ORM(ORM的基础概念) | 旧一篇: GZipStream实现压缩以及出现的问题

     在系统开发的过程中,我们总是需要使用配置文件来保存一些我们需要保存的系统参数,毕竟这是.Net时代,如果再使用注册表那就显得复杂了,毕竟操作注册表的API并不是哪么容易理解的。

    所以在.net应用程序中,都默认出现一个App.Config(对于 Web应用程序是Web.Config)我们可以将系统运行所需要的参数采用加密或者明文的方式保存在这个文件中。但是当我们需要大量的,并且有一定逻辑结构的数据,希望也能够保存到配置文件中,此时我们可能这样做:将这些数据构造成DataSet,然后使用DataSet.WriteXML直接写成XML文件,读取的时候直接使用DataSet.LoadXML。另外一种方式就是直接操作XML数据,使用XmlDocument

    第一种方法虽然是好,因为我们可以想操作数据库表一样操作我们的结构化的数据,可是在某些情况下,总觉得怪怪的。并且增加列等等这些的操作觉得及其难受。特别是我们需要使用这些数据的时候,我们首先要去读文档,了解DataSet中的每个表以及每个字段的含义,所以此方法不可取。

    那第二种方法呢,这个更不可取。如果我们增加了某个字段,或者修改了数据的机构,那我们的代码修改起来是在也是比较复杂的事情。

    那有什么更好的方式来解决这个问题的呢?

    既然微软可以使用App.ConfigWeb.Config,可以使用ComfigManager来对这两个配置文件来进行管理,让我们非常方便地进行使用,那我们为何不可设计自己的ConfigManager呢?

    需求:我们这里以菜单结构作为例子来描述我们的想法。

    菜单,包括主菜单项,比如系统里面的“文件”,“编辑”等等,包括子菜单,比如“文件”下的“保存”,“另存为”等,子菜单下也包括下级子菜单。总之这是一个完全结构化的数据格式,当然使用菜单来举例主要是这东西我们每天都见到,所以很容易理解,如:

    1. public class Menu
    2. {
    3.     private string _Name;
    4.     private string _Text;
    5.     private string _IconName;
    6.     //...这里可能还有其他你需要变量
    7.     private SubMenus _SubMenus;
    8.     /// <summary>
    9.     /// 注意,一定需要一个无参数的构造函数,否则序列化的时候出错
    10.     /// </summary>
    11.     public Menu()
    12.         : this("""""")
    13.     { }
    14.     public Menu(string name, string text, string iconname)
    15.     {
    16.         this._Name = name;
    17.         this._Text = text;
    18.         this._IconName = iconname;
    19.         this._SubMenus = new SubMenus();
    20.     }
    21.     /// <summary>
    22.     /// 菜单名
    23.     /// </summary>
    24.     [XmlAttribute("Name")]
    25.     public string Name
    26.     {
    27.         get { return this._Name; }
    28.         set { this._Name = value; }
    29.     }
    30.     /// <summary>
    31.     /// 菜单Text
    32.     /// </summary>
    33.     [XmlAttribute("Text")]
    34.     public string Text
    35.     {
    36.         get { return this._Text; }
    37.         set { this._Text = value; }
    38.     }
    39.     /// <summary>
    40.     /// 菜单的图标名
    41.     /// </summary>
    42.     [XmlAttribute("IconName")]
    43.     public string IconName
    44.     {
    45.         get { return this._IconName; }
    46.         set { this._IconName = value; }
    47.     }
    48.     /// <summary>
    49.     /// 子菜单
    50.     /// </summary>
    51.     public SubMenus SubMenus
    52.     {
    53.         get { return this._SubMenus; }
    54.         set { this._SubMenus = value; }
    55.     }
    56. }

    好,那我们菜单项包括子菜单,怎么表示呢?

    我们使用一个List来保存我们的子菜单,为了更为直观,我们定义一个SubMenus的类,继承于List<Menu>

    1. /// <summary>
    2. /// 子菜单列表
    3. /// </summary>
    4. public class SubMenus : List<Menu>
    5. }

    下面我们就来构造我们的菜单MenuStrip。一个MenuStrip中,同样包括多个菜单,比如“文件”“编辑”“视图”等等。

    MenuStrip中,我们提供Load()函数,用于加载我们的菜单数据,提供Save()用于保存我们设置好的菜单数据:

    1. public class MenuStrip
    2. {
    3.     //...您需要的其他变量
    4.     private SubMenus _SubMenus;
    5.     public MenuStrip()
    6.     {
    7.         this._SubMenus = new SubMenus();
    8.     }
    9.     public SubMenus SubMenus
    10.     {
    11.         get { return this._SubMenus; }
    12.         set { this._SubMenus = value; }
    13.     }
    14.     /// <summary>
    15.     /// 这里使用Static,方便调用
    16.     /// </summary>
    17.     /// <returns></returns>
    18.     public MenuStrip Load()
    19.     {
    20.         MenuStrip instance = new MenuStrip();
    21.         XmlSerializer xs = new XmlSerializer(typeof(MenuStrip));
    22.         StreamReader sr = new StreamReader(@"...\Menu.Config");
    23.         instance = xs.Deserialize(sr) as MenuStrip;
    24.         sr.Close();
    25.         return instance;
    26.     }
    27.     public void Save()
    28.     {
    29.         XmlSerializer xs = new XmlSerializer(typeof(MenuStrip));
    30.         StreamWriter sw = new StreamWriter(@"...\Menu.Config");
    31.         xs.Serialize(sw, this);
    32.         sw.Close();
    33.     }
    34. }

    测试代码如下:

    1. MenuStrip menustrip = new MenuStrip();
    2. //文件菜单
    3. Menu mnuFile = new Menu("mnuFile""文件(&F)""");
    4. mnuFile.SubMenus.Add(new Menu("mnuNew""新建"""));
    5. mnuFile.SubMenus.Add(new Menu("mnuSave""保存"""));
    6. mnuFile.SubMenus.Add(new Menu("mnuSaveAs""另存为"""));
    7. menustrip.SubMenus.Add(mnuFile);
    8. Menu mnuEdit = new Menu("mnuEdit""编辑(&E)""");
    9. mnuEdit.SubMenus.Add(new Menu("mnuCopy""复制"""));
    10. mnuEdit.SubMenus.Add(new Menu("mnuDelete""删除"""));
    11. mnuEdit.SubMenus.Add(new Menu("mnuCut""剪切"""));
    12. menustrip.SubMenus.Add(mnuEdit);
    13. menustrip.SubMenus.Add(new Menu("mnuView""视图(&V)"""));
    14. menustrip.Save();

    上面的代码构造了一个配置文件,保存后结果如下:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <MenuStrip xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    3.   <SubMenus>
    4.     <Menu Name="mnuFile" Text="文件(&F)" IconName="">
    5.       <SubMenus>
    6.         <Menu Name="mnuNew" Text="新建" IconName="">
    7.           <SubMenus />
    8.         </Menu>
    9.         <Menu Name="mnuSave" Text="保存" IconName="">
    10.           <SubMenus />
    11.         </Menu>
    12.         <Menu Name="mnuSaveAs" Text="另存为" IconName="">
    13.           <SubMenus />
    14.         </Menu>
    15.       </SubMenus>
    16.     </Menu>
    17.     <Menu Name="mnuEdit" Text="编辑(&E)" IconName="">
    18.       <SubMenus>
    19.         <Menu Name="mnuCopy" Text="复制" IconName="">
    20.           <SubMenus />
    21.         </Menu>
    22.         <Menu Name="mnuDelete" Text="删除" IconName="">
    23.           <SubMenus />
    24.         </Menu>
    25.         <Menu Name="mnuCut" Text="剪切" IconName="">
    26.           <SubMenus />
    27.         </Menu>
    28.       </SubMenus>
    29.     </Menu>
    30.     <Menu Name="mnuView" Text="视图(&V)" IconName="">
    31.       <SubMenus />
    32.     </Menu>
    33.   </SubMenus>
    34. </MenuStrip>

    您可能会说,这样也不见得很好啊,但是你是否发现,我们就像使用菜单对象一样来操作我们的Menu对象,我们不需要像使用DataSet那样首先要去了解其中每个数据库表的每个字段的含义,也不需要像使用XmlDocument那样去记住每个菜单项的位置。菜单项就是我们的Menu对象,我们可以增加不限级的子菜单,随意遍历我们的菜单等等

     

    另,通过这样的方式,可以在我们的应用中设计各种各样易于使用修改和维护的结构。

     

     

    发表于 @ 2008年08月31日 14:49:00|评论(loading...)|收藏

    新一篇: C#基础系列:实现自己的ORM(ORM的基础概念) | 旧一篇: GZipStream实现压缩以及出现的问题

    评论

    #5555 发表于2008-09-02 09:21:23  IP: 125.92.209.*
    你好,我的电脑浏览些网页的时候出现:运行时错误
    说明: 服务器上出现应用程序错误。此应用程序的当前自定义错误设置禁止远程

    查看应用程序错误的详细信息(出于安全原因)。但可以通过在本地服务器计算机

    上运行的浏览器查看。

    详细信息: 若要使他人能够在远程计算机上查看此特定错误信息的详细信息,请

    在位于当前 Web 应用程序根目录下的“web.config”配置文件中创建一个

    <customErrors> 标记。然后应将此 <customErrors> 标记的“mode”属性设置为

    “Off”。


    <!-- Web.Config 配置文件 -->

    <configuration>
    <system.web>
    <customErrors mode="Off"/>
    </system.web>
    </configuration>


    注释: 通过修改应用程序的 <customErrors> 配置标记的“defaultRedirect”属

    性,使之指向自定义错误页的 URL,可以用自定义错误页替换所看到的当前错误

    页。


    <!-- Web.Config 配置文件 -->

    <configuration>
    <system.web>
    <customErrors mode="RemoteOnly"

    defaultRedirect="mycustompage.htm"/>
    </system.web>
    </configuration>
    要怎么处理呀
    #RonoTian 发表于2008-09-02 09:59:19  IP: 219.133.255.*
    5555兄来轰炸我。。。
    你这个意思是,你的程序出了错误,但是由于你的配置文件设置成了禁止在浏览器中显示详细的错误信息。比如某些错误可能会这样“D:\xxx\xxx\.filename”这样的路径,说文件不存在啊什么的,这样的信息如果在浏览器中显示的话,那么黑客同志门就可以知道了你的物理路径名,他们就可能攻击你。所以配置文件中设置了不显示具体的错误。。。
    你想知道你的错误具体是什么,可以按照上面的提示信息,按照这上面的提示信息设置就可以了,这样你就可以知道具体错误是什么了,包括错误的堆栈信息。。。
    #tyr 发表于2008-09-02 14:55:58  IP: 61.139.94.*
    fgfdgdfg
    #younixianzai 发表于2008-09-03 20:45:52  IP: 220.177.80.*
    这双是什么呢~~
    #sweetch 发表于2008-09-04 13:19:21  IP: 221.216.20.*
    请问一下,如果调用Load() 这个函数,是不是在菜单中就可以把内容显示到相应项中?
    #RonoTian 发表于2008-09-04 13:59:12  IP: 219.133.83.*
    对,你调用了Load以后,通过遍历MenuStrip.SubMenus就可以根据这些信息来创建你需要的菜单了。
    #sweetch 发表于2008-09-05 17:32:54  IP: 221.218.38.*
    我觉得用序列化的方法太麻烦了,还是用Linq方便,个人意见,呵呵
    #dong 发表于2008-09-07 16:34:01  IP: 60.217.206.*
    我想把动态页面(.aspx)转换成静态页面 (.html)以提高运行速度,如何做到这一效果呢。
    #dong 发表于2008-09-07 16:34:09  IP: 60.217.206.*
    我想把动态页面(.aspx)转换成静态页面 (.html)以提高运行速度,如何做到这一效果呢。
    #网站建设 发表于2008-09-10 15:56:35  IP: 123.114.176.*
    还是用Linq方便
    #asdf 发表于2008-09-12 08:10:41  IP: 125.120.87.*
    asdf
    #enjoyeveryday 发表于2008-10-31 16:53:00  IP: 121.32.89.*
    菜单解决了 请问楼主咋跟权限挂钩起来了???比如我只能复制,他只能看到删除。请教!
    2008-11-01 16:11:16作者回复
    呵呵,这个仅仅是使用菜单这种具有层次结构的东西来演示自己的配置文件的设计方法。
    如果你真的希望实现权限控制应该也是可以的啊。
    在配置文件中采用插件的形式保存你的权限验证的代码所在的 Assembly、 namespace、class然后点击菜单的时候动态创建权限验证对象进行验证。。。
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © 老田