【问题标题】:Bing API Query Callback to Observable CollectionBing API 查询回调到 Observable 集合
【发布时间】:2014-11-21 05:54:39
【问题描述】:

使用这篇文章中的一些信息创建了一个 Windows 应用商店应用程序:How do I use the Bing Search API in Windows Phone?

目标

文本框 - 输入任何术语 搜索按钮 - 搜索该术语并填充使用 Bing API 检索到的图片的 GridView

问题

我得到了图片,它们是通过我的“OnQueryComplete”回调接收到的,但我不知道填充集合的正确方法是什么。由于我不知道如何等待这个调用,我(只是想看看我是否可以让它工作,它确实)添加了一个 while 循环(你可能会看到问题)。这样做的正确方法是什么?您如何处理用于填充 GridView 并让它等待完成的回调?

当前 ViewModel 代码

    public bool itemsFinished = false;
    private ObservableCollection<SearchResult> _ImageResults;
    public ObservableCollection<SearchResult> ImageResults {
        get {
            if (_ImageResults == null) {
                while (!itemsFinished) {
                    int i = 0;
                    i++;
                }
            }
            return _ImageResults;
        }
        set {
            _ImageResults = value;
        }
    }

    public SearchResultViewModel() {
       GetPictures("dogs");
    }


    public void GetPictures(string searchTerm) {
        // This is the query - or you could get it from args. 
        string query = searchTerm;
        // Create a Bing container. 
        string rootUri = "https://api.datamarket.azure.com/Bing/Search";
        var bingContainer = new Bing.BingSearchContainer(new Uri(rootUri));
        // Replace this value with your account key. 
        var accountKey = "myaccountkey";
        // Configure bingContainer to use your credentials. 
        bingContainer.Credentials = new NetworkCredential(accountKey, accountKey);
        // Build the query. 
        var imageQuery = bingContainer.Image(query, null, null, null, null, null, null);
        imageQuery.BeginExecute(OnQueryComplete, imageQuery);

        // var imageResults = imageQuery.Execute(); 
    }

    private void OnQueryComplete(IAsyncResult result) {
       // ImageResults.Clear();
        _ImageResults = new ObservableCollection<SearchResult>();
        var query = (DataServiceQuery<ImageResult>)result.AsyncState;
        var enumerableResults = query.EndExecute(result);
        int i = 0;
        foreach (var item in enumerableResults) {
            SearchResult myResult = new SearchResult();
            myResult.Title = item.Title;
            myResult.ImageUri = new Uri(item.MediaUrl);
            ImageResults.Add(myResult);
            i++;
            if (i >= 14) {
                break;
            }
        }
        itemsFinished = true;

    }

【问题讨论】:

  • 只是一个建议,但您可能还想在CodeReview 上寻求一些提示,因为您的代码确实存在一些问题:)
  • 这是一个粗略的概念证明,我正在学习如何使用 Bing API。我正在尝试任何事情来等待回调。

标签: c# xaml gridview windows-store-apps


【解决方案1】:

请原谅任何语法错误,我现在没有 Visual Studio 实例。

我看到的问题是您在收到内容时重置了ObservableCollection

试试如下:

private ObservableCollection<SearchResult> _ImageResults;
public ObservableCollection<SearchResult> ImageResults {
    get
    {
        return _ImageResults;
    }
    set {
        _ImageResults = value;
    }
}

public SearchResultViewModel() {
   _ImageResults = new ObservableCollection<SearchResult>(); // Just create it once.
   GetPictures("dogs");
}

private void OnQueryComplete(IAsyncResult result) {
    _ImageResults.Clear(); // Clear isn't bad, that way you keep your reference to your original collection!
    //_ImageResults = new ObservableCollection<SearchResult>(); // We already have one. ObservableCollection works best if you keep on working with the collection you have.
    var query = (DataServiceQuery<ImageResult>)result.AsyncState;
    var enumerableResults = query.EndExecute(result);
    int i = 0;
    foreach (var item in enumerableResults) {
        SearchResult myResult = new SearchResult();
        myResult.Title = item.Title;
        myResult.ImageUri = new Uri(item.MediaUrl);
        ImageResults.Add(myResult);
        i++;
        if (i >= 14) {
            break;
        }
    }
}

据我所知(遗憾的是无法测试)这应该可以工作,前提是您在 xaml 中以正确的方式绑定了您的 ObservableCollection

【讨论】:

  • 问题是当我尝试以这种方式实现它时,它没有给回调足够的时间来完成。我的集合没有被填充,因为尚未发生回调事件(从 API 获取 JSON 需要一秒钟)。因此,“GetPictures”已经完成,它没有被等待,所以 SearchResults 的集合没有被填充并且前端认为它已经完成了。我实现了 While 循环,因为它暂停了 getter,直到填充了集合。知道如何实现这样的目标吗?
  • 这应该通过使用ObservableCollection 来解决。每次您向/从集合中添加/删除 items 时,它都会向订阅了它的通知的任何人发送更新(您的 ListView 自己做)。
  • 这是一个 [ObservableCollection],它仍然没有更新。如果有帮助,我会在明天展示我的 XAML。
  • 没问题。你看过INotifyPropertyChanged吗?它也可能有帮助:)
猜你喜欢
  • 2011-06-09
  • 1970-01-01
  • 2018-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多