一个好老好老的老程序员了。
全部博文(915)
分类: Android平台
2018-07-08 15:43:39
在大多数实际应用程序中,代码隐藏文件需要引用XAML文件中定义的元素。 您在上一章的CodePlusXaml程序中看到了一种方法:如果代码隐藏文件知道XAML文件中定义的可视树的布局,它可以从根元素(页面本身)开始, 找到树中的特定元素。 此过程称为“在树上行走”,可用于定位页面上的特定元素。
通常,更好的方法是为XAML文件中的元素赋予类似于变量名的名称。 要执行此操作,请使用XAML固有的属性,称为Name。 因为前缀x几乎单独用于XAML固有的属性,所以此Name属性通常称为x:Name。
XamlClock项目演示了x:Name的使用。 这是包含两个Label控件的XamlClockPage.xaml文件,名为timeLabel和dateLabel:
点击(此处)折叠或打开
与第5章中的时钟程序一样,XamlClock使用Device.StartTimer来触发定期事件以更新时间和日期。 这是XamlClockPage代码隐藏文件:
点击(此处)折叠或打开
此计时器回调方法每秒调用一次。 该方法必须返回true才能继续计时器。 如果返回false,则计时器停止,必须通过另一次调用Device.Start?Timer重新启动。
回调方法引用timeLabel和dateLabel,就像它们是普通变量一样,并设置每个变量的Text属性:
这不是一个视觉上令人印象深刻的时钟,但它绝对是功能性的。
如何使用代码隐藏文件引用用x:Name标识的元素? 这很神奇吗? 当然不是。 当您检查XAML解析器在构建项目时从XAML文件生成的XamlClockPage.xaml.g.cs文件时,该机制非常明显:
点击(此处)折叠或打开
由于属性和完全限定类型,可能有点难以看到,但是当构建时XAML解析器咀嚼XAML文件时,每个x:Name属性都成为此生成的代码文件中的私有字段。这允许代码隐藏文件中的代码引用这些名称,就像它们是正常字段一样 - 它们肯定是。但是,字段最初为空。仅在运行时调用InitializeComponent时,才会通过FindByName方法设置两个字段,该方法在NameScopeExtensions类中定义。如果代码隐藏文件的构造函数尝试在InitializeComponent调用之前引用这两个字段,则它们将具有空值。
这个生成的代码文件还暗示了x的另一个规则:名称值现在非常明显但很少明确说明:名称不能复制代码后面文件中定义的字段或属性的名称。
因为这些是私有字段,所以只能从代码隐藏文件而不是其他类访问它们。如果ContentPage衍生产品需要将公共字段或属性公开给其他类,则必须自己定义它们。
显然,x:Name值在XAML页面中必须是唯一的。如果您在XAML文件中使用OnPlatform作为特定于平台的元素,这有时会成为问题。例如,这是一个XAML文件,它将OnPlatform的iOS,Android和WinPhone属性表示为属性元素,以选择三个Label视图之一:
点击(此处)折叠或打开
点击(此处)折叠或打开
这不起作用,因为多个元素不能具有相同的名称。
您可以使用Device.OnPlatform为它们提供不同的名称并处理代码隐藏文件中的三个名称,但更好的解决方案是使特定于平台的标记保持尽可能小。 在此示例中,除Text外,所有Label属性都相同,因此只有Text属性需要特定于平台。 这是PlatformSpecificLabels程序的版本,它包含在本章的示例代码中。 它有一个Label,除了Text属性外,一切都是平台独立的:
点击(此处)折叠或打开
点击(此处)折叠或打开