设为首页收藏本站language 语言切换
查看: 1983|回复: 0
收起左侧

VB.NET中建立动态属性和保存属性设置

[复制链接]
发表于 2010-2-25 10:29:37 | 显示全部楼层 |阅读模式
<p >  <b>摘要</b>:本文讲解怎样建立动态属性来补充Visual Basic .NET已暴露的属性,以及使用动态属性保存应用程序实例间的用户配置。<p >  <b>介绍</b><p >Visual Basic .NET中的动态属性提供了一条保存应用程序实例间属性设置的简单途径,它不需要借助注册表或者.ini文件。Visual Basic .NET在默认的情况下提供了大量的动态属性,你能够通过添加代码轻易的使其它属性变为动态的。<p >  例如,在默认的情况下,Windows Forms暴露了大量的动态属性,如MaximizeBox、MinimizeBox和ShowInTaskbar等等,但是没有暴露另外一些有用的属性,如Size或Location。<p >  动态属性保存在配置文件中,为了保存一个设置,配置文件必须修改。不可能要求终端用户在每次运行应用程序时修改配置文件。这样看来没有办法保存用户配置属性,例如窗体的最后的位置或者颜色。<p >  通过在应用程序中添加几行代码,你可以使任何属性象动态属性一样工作,使它可以被用户配置。本文将演示怎样设置动态属性,怎样使动态属性可以被用户配置,怎样建立新的动态属性。<p ><p >  <b>动态属性是怎样工作的</b><p >  动态属性通过在应用程序配置文件(Windows应用程序中是app.config,Web应用程序中是web.config)中存储属性值来工作。当在属性窗体中添加一个动态属性时,将会有一个key/value对被添加到配置文件的appSettings段。此外,一个configurationAppSettings.GetValue调用被添加到InitializeComponent过程;该返回值被用于设置属性的初始值。当你编辑配置文件中的值时,你不需要更改InitializeComponent过程中的代码就能够改变初始属性值。<p >  例如Windows Form的TopMost属性决定一个窗体是否始终出现在其它窗体的顶层。通常你在设计时设置该属性,但是可以使应用程序更加灵活。通过把TopMost属性变为动态属性,你能在应用程序配置后听从选择。<p >  <p >  <b>学习动态属性如何工作</b><p >  1、建立一个叫DynamicProps的Windows应用程序并选中窗体设计器。<p >  2、在属性窗体中查找(DynamicProperties)节点并展开它,点击(Advanced)属性后面的省略按钮来打开Dynamic Properties对话框。<p >  3、在Properties列表中找到TopMost属性并选中它。<p >  注意Form1.TopMost默认值设置为Key mapping,但是你可以在这儿输入任意名称作为一个键,但是在我们的例子中还是使用这个默认值。<p >  4、在解决方案管理器中选择app.config文件并打开它。<p >  <ccid_code>你应该看到&lt;appSettings&gt;段的&lt;add key=&quot;Form1.TopMost:false&quot; /&gt;行。该键与映射对话框的设置的默认键匹配,它的值是TopMost属性的默认值(false)。</ccid_code><p >  5、打开Form1的代码编辑器并展开标有Windows Form Designer generated code的段。在InitializeComponent过程中你可以看到下面的声明:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="f6f6f6" class="code"><pre><ccid_code>Dim configurationAppSettings As _   System.Configuration.AppSettingsReader = New System.Configuration.AppSettingsReader()</ccid_code></pre></td></tr></table></ccid_nobr><p >  这个声明建立了一个分析配置文件的AppSettingsReader类。<p >  该过程的下面代码是:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="f6f6f6" class="code"><pre><ccid_code>Me.TopMost = CType(configurationAppSettings.GetValue(&quot;Form1.TopMost&quot;, _   GetType(System.Boolean)), Boolean)</ccid_code></pre></td></tr></table></ccid_nobr><p >  这一行从配置文件中检索键Form1.TopMost,并把从配置文件中的Text数据转变为TopMost属性所要求的Boolean类型。<p >  6、运行该应用程序,可以看到窗体没有停留在顶层,关闭应用程序。<p >  7、打开app.config文件并把Form1.TopMost键的值改为true.<p >  8、重新运行该应用程序。<p >  这次窗体停留在顶层。如果你查看属性窗体的TopMost属性,会发现属性值改为true了。这是因为在属性和配置文件间有一个动态链接。<p >  下面将学习怎样在运行时使TopMost可以被用户配置。<p ><p >  <b>保存用户配置的动态属性</b><p >  尽管修改配置文件改变动态属性很有用,但是如果用户可以配置属性将更加有用,这样用户可以从应用程序中改变动态属性。此外,应用程序应该在实例间保存和恢复设置。为了实现这个功能,你必须首先添加了一个用户界面来设置该属性。<p ><p >  <b>为了保存用户可配置动态属性</b><p >  1、给窗体添加一个CheckBox控件,将它的Text属性设置为Stay on top。<p >  2、添加下面的CheckBox1_CheckedChanged事件处理程序代码:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="f6f6f6" class="code"><pre><ccid_code>rivate Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, _   ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged      Me.TopMost = CheckBox1.CheckedEnd Sub</ccid_code></pre></td></tr></table></ccid_nobr><p >  3、将该检查框的Checked属性改为true,这样该控件的值与TopMost属性的初始化设置匹配。<p >  4、运行应用程序<p >  当检查框被选中时,窗体停留在顶层,清除时,窗体没有停留在顶层。<p >  5、确认该检查框清除了并关闭应用程序。<p >  6、打开app.config文件可以发现TopMost属性的值仍为true。<p >  这使怎样发生的?尽管应用程序在初始化过程中能读入配置文件,但是当它们改变时没有办法自动地将值写入配置文件。你必须添加一些代码。<p >  你能够添加CheckedChanged事件处理程序代码,这样每次属性改变后,配置文件可以被更新。在应用程序关闭时简单地更新配置文件效率更高。<p >  7、在Form1_Closing事件处理程序中添加下面的代码:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="f6f6f6" class="code"><pre><ccid_code>rivate Sub Form1_Closing(ByVal sender As Object, ByVal e As _   System.ComponentModel.CancelEventArgs) Handles MyBase.Closing   ' 使用反射查找配置文件中的位置   Dim Asm As System.Reflection.Assembly = _      System.Reflection.Assembly.GetExecutingAssembly   Dim strConfigLoc As String   strConfigLoc = Asm.Location   '配置文件再应用程序的bin目录,因此需要删除文件名   Dim strTemp As String   strTemp = strConfigLoc   strTemp = System.IO.Path.GetDirectoryName(strConfigLoc)      '为配置文件定义一个FileInfo对象   Dim FileInfo As System.IO.FileInfo = New _System.IO.FileInfo(strTemp &amp; &quot;\DynamicProps.exe.config&quot;)   '将配置文件读入XML DOM   Dim XmlDocument As New System.Xml.XmlDocument()   XmlDocument.Load(FileInfo.FullName)   '找到正确的节点并将它的值改为新的   Dim Node As System.Xml.XmlNode   For Each Node In XmlDocument.Item(&quot;configuration&quot;).Item(&quot;appSettings&quot;)      '略过注释      If Node.Name = &quot;add&quot; Then         If Node.Attributes.GetNamedItem(&quot;key&quot;).Value = &quot;Form1.TopMost&quot; Then            Node.Attributes.GetNamedItem(&quot;value&quot;).Value = CType(Me.TopMost, String)         End If      End If   Next Node   '保存修改过的配置文件   XmlDocument.Save(FileInfo.FullName)End Sub</ccid_code></pre></td></tr></table></ccid_nobr><p >  8、再次运行应用程序,清除检查框并关闭应用程序。<p >  9、打开app.config文件,Form1.TopMost的值变为false。<p >  如果你再次运行应用程序,窗体不再停留在顶层。<p >  为什么检查框仍然选中了?如果你测试窗体的行为,会发现它并不停留在顶层,因此该属性设置没有保存。问题是检查框的Checked属性没有同步。<p >  10、添加下面的Sub_New过程代码,紧跟在InitializeCompoment调用后面,来同步获取Checked属性。<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="f6f6f6" class="code"><pre><ccid_code>  CheckBox1.Checked = Me.TopMost</ccid_code></pre></td></tr></table></ccid_nobr><p >  现在运行应用程序,检查框的状态正确的反映了TopMost行为。但还是有一个问题:如果选中了检查框,关闭并重新启动应用程序,检查框不再被选中。为什么?实际上有两个配置文件--在解决方案管理器中是app.config文件,在bin目录下面是appname.exe.config文件。如果你仔细查看代码,你会发现实际上将值保存在DynamicProps.exe.config文件中。你可以在解决方案管理器中点击Show All Files看到这个文件。<p >  每次应用程序建立时,app.config文件的内容复制到DynamicProps.exe.config文件,覆盖所有的改变。当应用程序展开时,DynamicProps.exe.config文件随着应用程序一起展开到应用程序的目录中。你可以直接写app.config文件,但是因为它停留在应用程序下面的层次,在展开后应用程序无法找到该文件。运行时为了应用那些改变,在应用程序再次运行前,你需要打开DynamicProps.exe.config并将内容复制到app.config文件。<p >  如果你要保存没有作为动态属性暴露的属性怎么办呢?下面将讲解怎样实现更多的动态属性。<p ><p >  <b>建立新的动态属性</b><p >  作为暴露的默认动态属性的补充,你也许想保存其它的属性。例如,如果用户移动了窗体后我们想保存窗体的位置,这样窗体下次就可以在该位置打开。尽管窗体的Location属性没有作为动态属性暴露,你也可以修改app.config文件使它象动态属性一样工作。<p >  <b>为了建立一个新动态属性</b><p >  1、在app.config文件的TopMost属性行下加入下面两行:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="f6f6f6" class="code"><pre><ccid_code>&lt;add key=&quot;Form1.X&quot; value=&quot;0&quot; /&gt;&lt;add key=&quot;Form1.Y&quot; value=&quot;0&quot; /&gt;</ccid_code></pre></td></tr></table></ccid_nobr><p >  2、为了保存,关闭app.config文件,否则应用程序每次运行都会提示你。<p >  3、在过程的最后加上下面的代码,它将改变Sub_New事件处理程序从配置文件中读取值。<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="f6f6f6" class="code"><pre><ccid_code>Dim configReader As System.Configuration.AppSettingsReader = New _System.Configuration.AppSettingsReader()Dim x As Integer, y As Integer' 从配置文件中检索值并转化为整型x = CType(configReader.GetValue(&quot;Form1.X&quot;, GetType(System.Int32)), Integer)y = CType(configReader.GetValue(&quot;Form1.Y&quot;, GetType(System.Int32)), Integer)' 使用新的x和y设置位置Me.Location = New System.Drawing.Point(x, y)</ccid_code></pre></td></tr></table></ccid_nobr><p >  请注意你建立了一个新的AppSettingsReader对象,因为在InitializeComponent过程中使用的对象不能访问。在配置文件中X和Y属性是分离的,因此你需要逐个设置。最后,Location属性使用Point对象作为参数,这样你就建立了一个指定了X和Y的相应的点。<p >  4、修改Form1_Closing事件处理程序来保存Location.X 和Location.Y到配置文件。添加下面的代码到行If Node.Name = "add" Then后面:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="f6f6f6" class="code"><pre><ccid_code>If Node.Attributes.GetNamedItem(&quot;key&quot;).Value = &quot;Form1.X&quot; Then   ' 将X转化为字符串   Node.Attributes.GetNamedItem(&quot;value&quot;).Value = CType(Me.Location.X, String)End IfIf Node.Attributes.GetNamedItem(&quot;key&quot;).Value = &quot;Form1.Y&quot; Then   Node.Attributes.GetNamedItem(&quot;value&quot;).Value = CType(Me.Location.Y,String)End If</ccid_code></pre></td></tr></table></ccid_nobr><p >  5、运行应用程序,移动窗体,接着关闭应用程序并重新启动它。<p >  窗体应该显示在原来的位置,但是没有。为什么呢?在初始化过程中,Location属性被StartPosition属性重载了,而StartPosition的默认值是WindowsDefault,这意味着Windows将决定窗体的初始位置。<p >  6、在过程再添加一个新行,这样属性设置才会实现:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="f6f6f6" class="code"><pre><ccid_code>Me.StartPosition = FormStartPosition.Manual</ccid_code></pre></td></tr></table></ccid_nobr><p >  这次你运行并重新启动应用程序时,窗体就恢复到预计的先前的位置了。<p ><p >  <b>结论</b><p >  如你所见,建立自己的动态属性并不困难,只需要在初始化和终止过程中加上几行代码。尽管本文讨论的是Windows应用程序,相同的技术可以简单地用于Web应用程序。<p ><center>(责任编辑 <ccid_nobr>西门吹雪</ccid_nobr>)</center><p align="center"></p></p>
您需要登录后才可以回帖 登录 | 论坛注册

本版积分规则

QQ|Archiver|手机版|小黑屋|sitemap|鸿鹄论坛 ( 京ICP备14027439号 )  

GMT+8, 2025-4-8 23:42 , Processed in 0.125002 second(s), 23 queries , Redis On.  

  Powered by Discuz!

  © 2001-2025 HH010.COM

快速回复 返回顶部 返回列表