Windows 8 Metro应用的开发中可以通过使用await、async关键字很方便的实现异步处理。
在CS应用中,画面上数据表示通常的做法一般是设置好画面控件的数据绑定后, 先从网络API获取数据,再自动的将数据通过数据绑定表示在画面上。
但是在学习过程中遇到了问题,发现在画面初期化时,调用await异步处理获取数据后,得到的数据并没有显示在画面上。
查阅了msdn官方的说明,作为数据源的model必须实现INotifyPropertyChanged接口,以响应数据变化并自动调用系统引擎表示数据。
但是比较了msdn官方示例中举的例子,并不是异步调用获取数据后更新画面表示,而是手动点击按钮后更新数据。
msdn数据绑定示例: XAML data binding sample
对比练习用的代码,model类部分的代码与示例的方法完全一致,但任然无法将数据显示到画面上。
大致的代码如下
XAML代码:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="城市名" FontSize="28" TextAlignment="Center" VerticalAlignment="Center" Margin="5,0,5,0"/>
<TextBlock Text="{Binding Path=CityName}" FontSize="28" TextAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0" Grid.Column="1"/>
</Grid>
XAML.CS代码:
private TestEntity testEntity;
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
await Task.Delay(TimeSpan.FromSeconds(3));
testEntity = new TestEntity();
testEntity.CityName = "Test City";
this.DataContext = testEntity;
}
model类代码:
class TestEntity : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _CityName;
/// <summary>
/// 都市名
/// </summary>
public string CityName
{
get { return _CityName; }
set
{
_CityName = value;
NotifyPropertyChanged("CityName");
}
}
protected void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
}
经过研究,发现当使用异步获取数据时,需要先将model类实例化后指定给对象控件作为数据源。
异步处理中获取的数据, 不能重新通过new来定义新的内存地址,否则就会绑定失败,数据无法表示到画面上。
代码修改很简单,只需要将代码的执行顺序改变一下即可:
private TestEntity testEntity;
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
testEntity = new TestEntity();
this.DataContext = testEntity;
await Task.Delay(TimeSpan.FromSeconds(3));
testEntity.CityName = "Test City";
}