WPF之XMAL对象引用总结

发布时间:2016-12-11 4:51:52 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"WPF之XMAL对象引用总结",主要涉及到WPF之XMAL对象引用总结方面的内容,对于WPF之XMAL对象引用总结感兴趣的同学可以参考一下。

             我们应该都知道,XMAL是一种声明式语言,XMAL的标签声明的就是对象。一个XMAL标签会对应着一个对象,这个对象一般会是一个控件类的实例。在.Net平台上,所有类都是引用类型,我们是通过引用来访问对象实例。当一个对象实例不再被任何引用者引用时,它将自动被GC回收。             在WPF开发过程中,后台代码经常会操作前台XMAL声明的控件对象实例,这就涉及到如何查找这些控件对象的引用。             有两种方式可以查找前台控件对象的引用,以下分别介绍:            方式1:利用引用者的层级关系来查找控件对象引用                 window x:Class="WpfApplication1.Window1"                          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          xmlns:local="clr-namespace:WpfApplication1"                         Title="WindowServer" Height="300" Width="300" MaxWidth="500" MaxHeight="600" MinHeight="200" MinWidth="200">                           <StackPanel >                                         <Button Content="OK" Margin="5" Click="Button_Click"/>                                         <TextBox  Margin="5,0" Height="100" >                            </StackPanel>                 </Window>        以上是用XMAL申明了两个控件对象实例,下面后台代码Button控件点击事件器,需要完成对TextBox的内容填字一段字符串。           private void Button_Click(object sender, RoutedEventArgs e)          {              StackPanel stackPanel = this.Content as StackPanel;  //this.Content属性引用着StackPanel的实例              TextBox textBox = stackPanel.Children[1] as TextBox;   //StackPanel实例的Children[1]引用着TextBox实例              textBox.Text = "Hello,World!";          }       通过这个关系就可以一路查找下来,同时进行类型的转换。看懂以上关系,那么就很容易知道stackPanel.Childere[0]引用的对象是什么了。             方式2:利用XMAL申明的控件引用变量名引用控件对象实例        window x:Class="WpfApplication1.Window1"                          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                          xmlns:local="clr-namespace:WpfApplication1"                         Title="WindowServer" Height="300" Width="300" MaxWidth="500" MaxHeight="600" MinHeight="200" MinWidth="200">                           <StackPanel >                                         <Button x:Name="button" Content="OK" Margin="5" Click="Button_Click"/>                                         <TextBox x:Name="textBox"  Margin="5,0" Height="100" >                            </StackPanel>                 </Window>        我们从方式1很容易发现,使用这种方法访问UI上的所有控件对象实例太繁琐了。XMAL通过为对象声明引用变量,后台代码通过引用变量就可以直接获取到该对象引用。       而XMAL申明对象的引用变量是使用x:Name来做到的。原则上,所有UI控件都存在该属性。      查看以上XMAL申明,发现它和方式1唯一的区别是控件了x:Name的引用变量声明。这时,我们的后台代码获取控件对象实例方法如下:           private void Button_Click(object sender, RoutedEventArgs e)          {             // StackPanel stackPanel = this.Content as StackPanel;  //this.Content属性引用着StackPanel的实例              //TextBox textBox = stackPanel.Children[1] as TextBox;   //StackPanel实例的Children[1]引用着TextBox实例              textBox.Text = "Hello,World!";          }        这段代码通过XMAL申明的对象引用变量直接访问对象,相对方式1确实简洁多了,呵呵。那么如何我们需要访问Button对象呢,当然直接使用button就OK了。        这里需要提一点,x:Name申明对象引用变量的同时,如果控件存在Name属性,那么采用x:Name将一举两得,可自动对Name属性赋值,赋值的名称当然与引用变量名称相同。所以,建议使用x:Name,因为它的功能已涵盖了控件的Name属性功能,可以增强代码的统一性和可读性。        ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------        后台代码除了经常访问前台XMAL声明的控件对象实例,还会经常访问前台声明的控件资源。        看一下以下这段XMAL申明:        <Window x:Class="WpfApplication1.Window1"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:local="clr-namespace:WpfApplication1"     xmlns:sys="clr-namespace:System;assembly=mscorlib"     Title="WindowServer" Height="300" Width="300" MaxWidth="500" MaxHeight="600" MinHeight="200" MinWidth="200">     <Window.Resources>         <sys:String x:Key="myString">Hello,World!</sys:String>     </Window.Resources>     <StackPanel>         <Button x:Name="button1" Content="Send Command" Margin="5" Click="Button_Click" >         <TextBox x:Name="textBoxA" Margin="5,0" Height="100" >     </StackPanel>  </Window>      这段XMAL声明和之前的没什么区别,除了黑体字部分。这段申明是向Window.Resources资源字典添加一个条目,条目的内容是一段字符串。     再仔细观察,你会发现除了字符串,还有x:Key="myString"这一语句。它的作用是干嘛呢,很简单是建立资源字典的键值对,方便索引资源条目。如何使用过C++的STL,对Map应该就不陌生。这个x:Key就相当于Map的key。下面看一看,后台代码如何访问这段字符串。          private void Button_Click(object sender, RoutedEventArgs e)          {                 string str = this.FindResource("myString") as string;  //调用一个拥有Resource属性对象的FindResource方法就可以从资源字典里检索资源                 this.textBox.Text = str;              }         值得注意一下,检索资源返回的是Object对象,需要根据相应类型转换即可。         除了后台代码经常检索控件资源,前台控件也可能会访问该资源,引用的方法是使用StaticResource或DynamicResource.                  下面的示例在page的根元素定义了一个SolidColorBrush画刷作为一个资源,并展示如何用它来设置Page中子元素的属性 <Page Name="root" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Page.Resources>     <SolidColorBrush x:key=”MyBrush” Color=”Gold”/>     <Style TargetType=”Border” x:Key=”PageBackground”>        <Setter Property=”Background” Value=”Blue”/>     </Style> <Page.Resources>     <SolidColorBrush x:Key="MyBrush" Color="Gold"/>     <Style TargetType="Border" x:Key="PageBackground">       <Setter Property="Background" Value="Blue"/>     </Style>    </Page.Resources>  <StackPanel>     <DockPanel>         <Button DockPanel.Dock="Top" HorizontalAlignment="Left" Height="30" Background="{StaticResource MyBrush}" Margin="40">Button</Button>               </DockPanel>  </StackPanel> </Page>   每个框架级别的元素(FrameworkElement或FrameworkContentElement)都有一个Resources属性,我们可以在任何元素上定义资源,不过习惯上在根元素上定义,如上面 的xmal代码中<Page.Resources/>定义资源。        通过属性x:Key给每个资源赋予一个唯一的关键字。这样我们就可以在Xmal的其它地方通过Key值来操作对应的资源了。如下示例,使用资源给元素的属性赋值 <Button Background=”{StaticResource MyBrush}” />   StaticResource 和DynamicResource的区别:   资源可以被当作StaticResource和DynamicResource两种类型来引用。 当引用资源时,下面的考虑将影响你是选择StaticResource还是DynamicResource来它。 1〉 如何为应用程序创建资源(资源是在一个Page中,在APP范围还是在松散的Xaml中或仅仅在程序集中) 2〉 应用程序功能:是否在运行时改变资源 3〉 每个资源引用类型不同的寻找行为 StaticResources StaticResources在如下情况下使用比较好 1〉 在资源第一次引用之后无需再修改资源的值 2〉 StaticResource引用不会基于运行时的行为进行重新计算。比如在重新加载Page的时候。 3〉 当需要设置的属性不是DependencyObject或Freezable类型的时候,需要用staticResource 4〉 当需要将资源编译到dll中,并打包为程序的一部份,或者希望在各应用程序之间共享 5〉 当需要为一个自定义控件创建一个theme,并theme中使用资源,就需要使用StaticResource。因为StaticResource的资源查找行为时可预测的,并且本身包含在theme中。而对于DynamicResource,即使资源是定义在theme中,也只能等到运行时确定,导致一些可能意料不到的情况发生。 6〉 当需要使用资源设置大量的依赖属性的时候(dependency property),依赖属性具有属性系统提供的值缓存机制,所以如果能在程序装载时设置依赖属性的值,依赖属性就不需要检查自己的值并返回最后的有效值了。可以获得显示时的好处。 Static resource 查询行为 1〉 查找使用该资源的元素的resource字典 2〉 顺逻辑树向上查找父元素的资源字典,直到根节点 3〉 查找Application资源 4〉 不支持向前引用。即不能引用在引用点之后才定义的资源   Dynamic Resource Dynamic resources一般使用在如下场合 1〉 资源的值依赖一些条件,而该条件直到运行时才能确定。这包括系统资源,或是用户可设置的资源。例如,可以创建引用系统属性诸如SystemColors,SystemFonts来设置值,这些属性是动态的,他们的值来自于运行环境和操作系统 2〉 为自定义控件引用或创建theme style 3〉 希望在程序运行期间调整资源字典的内容 4〉 希望资源可以向前引用 5〉 资源文件很大,希望在运行时加载 6〉 要创建的style的值可能来自于其它值,而这些值又依赖于themes或用户设置 7〉 当引用资源的元素的父元素有可能在运行期改变,这个时候也需要使用动态资源。因为父元素的改变将导致资源查询的范围。 Dynamic resource 查询行为 1〉 查找使用该资源的元素的resource字典 如果元素定义了一个Style 属性,将查找Style中的资源字典 如果元素定义了一个Template属性,将查找FrameworkTemplate中的资源字典 2〉 顺逻辑树向上查找父元素的资源字典,直到根节点 3〉 查找Application资源 4〉 查找当前激活状态下的theme资源字典。 5〉 查找系统资源 Dynamic resource的限制条件 1〉 属性必须是依赖属性,或是Freezable的

上一篇:编写你自己的单点登录(SSO)服务
下一篇:结构体作为map的key或放入set中,需要重载<运算符

相关文章

相关评论