MSDN Library

如何保留 Windows Phone 的 OData 客户端状态

2012/2/9

若要保留使用 Windows Phone 开放数据协议 (OData) 客户端库的应用程序的状态,您需要使用 DataServiceState 类实例。有关更多信息,请参阅 Windows Phone 的开放数据协议 (OData) 客户端

提示提示:

如果尝试直接在状态字典中存储所跟踪的实体对象,则会导致在序列化过程中出错。如果您需要保持各个所跟踪对象的状态,请改为存储实体的 URI。通过调用 TryGetUri(Object, Uri%) 方法,可以获取实体对象的 URI。随后,您便可以将存储的 URI 传递到 TryGetEntity<(Of <<'(TEntity>)>>)(Uri, TEntity%) 方法,以便从还原的 DataServiceContext 中检索对象。

本主题中的示例显示如何在调用 OnNavigatingFrom(NavigatingCancelEventArgs) 方法将单个页面的数据服务状态保存到页面的状态字典中,并在调用 OnNavigatedTo(NavigationEventArgs) 时还原该数据。该示例演示了如何使用 DataServiceState 类序列化对象以保留状态以及如何还原它们的基本知识。但是,我们建议为您的多页数据应用程序采用模型视图查看模型 (MVVM) 设计模式。当使用 MVVM 时,数据将存储在 Deactivated 事件处理程序方法中应用程序的 State 字典中,并且将在 Activated 事件处理程序中还原。在此情况下,应由 ViewModel 执行激活和取消激活。有关更多信息,请参阅演练:在 Windows Phone 中结合使用 OData 和 MVVM

本主题中的示例将扩展如何使用 Windows Phone 的 OData 服务中的单页应用程序。该应用程序使用发布在 OData 网站上的 Northwind 示例数据服务。此示例数据服务是只读的;如果尝试保存更改,则将会返回错误。

下面的示例显示了如何序列化数据服务状态,以及如何将状态存储在页面的状态字典中。该操作将在页面的 OnNavigatingFrom(NavigatingCancelEventArgs) 方法中执行。

protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
    // Define a dictionary to hold an existing 
    // DataServiceCollection<Customer>. 
    var collections = new Dictionary<string, object>();
    collections.Add("Customers", customers);

    // Serialize the data service data and store it in the page state.      
    this.State["DataServiceState"] =
        DataServiceState.Serialize(context, collections);
}

下面的示例显示了如何还原页面状态字典中的数据服务状态。此还原操作将在页面的 OnNavigatedTo(NavigationEventArgs) 方法中执行。

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    // Get the object data if it is not still loaded.
    if (!this.isDataLoaded)
    {
        object storedState;
        DataServiceState state;

        // Try to get the serialized data service state.
        if (this.State.TryGetValue("DataServiceState", out storedState))
        {
            // Deserialize the DataServiceState object.
            state = DataServiceState.Deserialize(storedState as string);

            // Set the context from the stored object.
            var restoredContext = (NorthwindEntities)state.Context;

            // Set the binding collections from the stored collection.
            var restoredCustomers = state.RootCollections["Customers"]
                as DataServiceCollection<Customer>;

            // Use the returned data to load the page UI.
            this.LoadData(restoredContext, restoredCustomers);
        }
        else
        {
            // If we don't have any data stored, 
            // we need to reload it from the data service.
            this.LoadData();
        }
    }
}

请注意,在此示例中,我们必须首先检查 isDataLoaded 变量以确定数据在内存中是否仍处于活动状态,当应用处于睡眠状态但未终止时,数据在内存中可能处于活动状态。如果内存中没有数据,我们必须首先尝试从状态字典还原状态,然后调用使用存储数据绑定到 UI 的 LoadData 方法版本。如果数据未存储在状态字典中,我们需要调用从数据服务获取数据的 LoadData 方法版本,该操作在首次执行应用程序时完成。

该示例显示了从上一个示例中调用的两种 LoadData 方法重载。

// Display data from the stored data context and binding collection. 
public void LoadData(NorthwindEntities context, DataServiceCollection<Customer> customers)
{
    this.context = context;
    this.customers = customers;

    this.isDataLoaded = true;
}
private void LoadData()
{
    // Initialize the context and the binding collection. 
    context = new NorthwindEntities(northwindUri);
    customers = new DataServiceCollection<Customer>(context);

    // Define a LINQ query that returns all customers.
    var query = from cust in context.Customers
                select cust;

    // Register for the LoadCompleted event.
    customers.LoadCompleted
        += new EventHandler<LoadCompletedEventArgs>(customers_LoadCompleted);

    // Load the Customers feed by executing the LINQ query.
    customers.LoadAsync(context.Customers);

}
void customers_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
    if (e.Error == null)
    {
        // Handle a paged data feed.
        if (customers.Continuation != null)
        {
            // Automatically load the next page.
            customers.LoadNextPartialSetAsync();
        }
        else
        {
            // Set the data context of the list box control to the sample data.
            this.LayoutRoot.DataContext = customers;

            this.isDataLoaded = true;
        }
    }
    else
    {
        MessageBox.Show(string.Format("An error has occurred: {0}", e.Error.Message));
    }
}

显示:
© 2016 Microsoft