Metro应用开发其实和Android应用开发有一点相似。前台使用XML进行控件布局,后台进行赋值和算法操作,这种做法把控件独立于后台编程之外,可视化的布局是很方便清晰的。比较特别的是Metro应用用的不是一般的XML,而是XAML,虽然基本的语法是一致的,但是控件的使用和嵌套要灵活许多。
根据作业要求,是要把上次完成的控制台版天气预报小程序搬到Metro应用上。因为想着后台操作基本上已经完成了,所以先从界面布局下手。
首先是拖过来一个Hub控件。Hub控件下有若干个HubSection子项,每个子项下默认是DataTemplate。犹豫了几秒之后百度了一下DataTemplate,发现是和ASP.NET前端中模版列差不多的东西,如果是要绑定列表项的话会方便许多(虽然现在我还用不着。
但是DataTemplate带来的一个问题就是,因为DataTemplate中的控件是根据数据量进行加载的,所以不能在后台直接用控件名进行访问赋值。
现在的问题是,我需要把获取到的天气数据显示到DataTemplate下的TextBlock中,但是我不能在后台直接给这个TextBlock赋值。
(其实在后台对DataTemplate中控件进行赋值的方法也是有的,大致上是通过在DataTemplate中逐个查找的方式来实现,但是如果控件数量很多,这时工作量就会很大而效率很低,并不是科学的解决方案。)
科学的解决方案是通过绑定。但是新的问题又来了,虽然在ASP.NET中用过数据绑定(而且觉得很好用),但是Metro应用中的绑定……怎么实现谁来告诉我……
好的最后是度娘告诉了我。
查阅了文档和资料,了解到绑定有五种模式,OneWay、TwoWay、OnWayToSource、Default以及OneTime,亦即单向、双向、逆向、默认和一次性的绑定。
因为对语法还不熟悉,这次尝试使用了最简单的匿名绑定。因为没有实现INotifyPropertyChanged接口(向绑定控件发送数据更改通知),所以源数据每次改变后都需要再次绑定才能在界面上显示更改。
XAML:
<Hub Header="天气预报">
<HubSection x:Name="currentHub" Header="" Width="300">
<DataTemplate>
<TextBlock Text="{Binding}"
Style="{ThemeResource BodyTextBlockStyle}" />
</DataTemplate>
</HubSection>
</Hub>
C#:
currentHub.DataContext = currentData;
如果控件显示的都是相关的属性,可以把数据封装进一个类对象,对整个对象进行绑定。