【问题标题】:GridView doesn't show items async loader, doesn´t refresh itemsGridView 不显示项目异步加载器,不刷新项目
【发布时间】:2013-06-23 05:24:58
【问题描述】:

我正在开发一个 Win8 应用程序:

我有一个通过 json 从 web 服务获取项目的数据源类:

public class DataSourceCapitulos
{
    public ObservableCollection<capitulo> ListaCapitulos { get; set; }
    public DataSourceCapitulos()
    {
        CargarCapitulos();
    }


    public async void CargarCapitulos()
    {
        var resourceUri = Cie10Uri.CapitulosUri;
        HttpClient httpClient = new HttpClient();
        bool error = false;
        HttpRequestException exception = null;
        try
        {
            string response = await httpClient.GetStringAsync(resourceUri);
            ListaCapitulos = new ObservableCollection<capitulo>(JsonConvert.DeserializeObject<List<capitulo>>(response));
        }
        catch (HttpRequestException e)
        {
            error = true;
            exception = e;
        }
        if (error)
        {
            MessageDialog adv = new MessageDialog(string.Format("La consulta {0}, devolvió:{1}", resourceUri, exception.Message), "No se pudo consultar!!! ");
            adv.Commands.Add(
                new UICommand("Ok")
            );
            await adv.ShowAsync();
        }
    }
}

并且有一个具有此来源的 XAML 表单:

<Page.Resources>
    <data:DataSourceCapitulos x:Key="DataSourceCapitulos"></data:DataSourceCapitulos>
</Page.Resources>

最后是一个 GridView,它的源项目指向 DataSourceCapitulos 的 ListaCapitulos 属性,如下所示:

    <GridView Grid.Column="1" Grid.Row="1" ItemsSource="{Binding Source={StaticResource DataSourceCapitulos},Path=ListaCapitulos}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Height="250" Width="250">
                    <Grid.Background>
                        <ImageBrush ImageSource="{Binding Imagen}"/>
                    </Grid.Background>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition Height="90"/>
                    </Grid.RowDefinitions>
                    <Rectangle >
                        <Rectangle.Fill>
                            <SolidColorBrush Color="#FF122951" Opacity="0.6"/>
                        </Rectangle.Fill>
                    </Rectangle>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </GridView>

直到这里我的应用程序运行没有问题,但问题是它没有显示项目,甚至 ListaCapitulos 也如我预期的那样填充。

这是 MainPage.xaaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    /// <summary>
    /// Se invoca cuando esta página se va a mostrar en un objeto Frame.
    /// </summary>
    /// <param name="e">Datos de evento que describen cómo se llegó a esta página. La propiedad Parameter
    /// se usa normalmente para configurar la página.</param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }
}

有什么我想念的吗?

【问题讨论】:

    标签: xaml windows-8 windows-runtime microsoft-metro winrt-xaml


    【解决方案1】:
    1. 在 XAML 中,设置 ItemsSource="{Binding listaCapitulos}(ObservableCollection)。

    2. 在页面的 C# 文件中,您需要一个 DataSourceCapitulos 类的实例,例如 DataSourceCapitulos ChaptersVm = new DataSourceCapitulos();(作为成员,您需要多次访问它)。

    3. 将gridview(XAML 中应该显示章节的那个)DataContext 设置为该实例。您可以在 C# 中执行此操作,ChaptersGridView.DataContext = ChaptersVm

    你是说你知道你有 ListaCapitulos 中的章节,这意味着你没有正确绑定它们以显示。

    另外,我看到async void CargarCapitulos() 是异步的,您在构造函数中调用它,但会同步运行。收集章节时,您的应用可能无法流畅运行。

    更新

    虽然我不太确定第一种方法,但我可以想到两种方法可以保持Cargar Capitulos async 的调用。

    1) 等待新方法中的方法调用(我不太确定这是否能解决问题):

    在构造函数中:

    public DataSourceCapitulos()
    {
        LoadCapitulos();
    }
    

    你在LoadCapitulos 身体的哪个位置:

    public async void LoadCapitulos()
    {
        //this awaits the chapters to load (you were missing await,
        //but you can't use await in a constructor, so this is a work-around
        await CargarCapitulos(); 
    }
    

    如果 1) 不起作用,请尝试 2​​) 肯定会起作用,但您必须进行一些更改:

    2) 如果您对包含章节的集合进行了一些更改,您的 ObservableCollection 将不会通知 UI 任何更新。为此,您必须使用INotifyPropertyChanged 接口并实现其成员。如果您使用了 Windows 8 App 的高级模板,在 Common 文件夹中,您有一个名为 BindableBase 的类 - 尝试通过继承它直接使用它。另外,您必须在ObservableCollectionsetter 中调用OnPropertyChanged() 事件,这样当章节集合发生变化时,UI 也会通过绑定发生变化:

    public class DataSourceCapitulos : BindableBase
    {
        private ObservableCollection <capitulo> _listaCapitulos;
        public ObservableCollection <capitulo> ListaCapitulos
        {
            get 
            {
                return _listaCapitulos;
            }
            set
            {
                _listaCapitulos = value;
                OnPropertyChanged(); //This notifies of changes of collection
            }
         }
    

    但是,如果您没有 BindableBase,只需实现INotifyPropertyChanged,其余部分看起来就像我之前写的一样。通过这些提供通知的更改,章节应该显示在 UI 上,即使它们稍后被加载,在 UI 加载之后。

    但我会说你应该实现它以使通知更改产生任何效果。否则,您可以使用简单的 Capitulos 列表(怪异的西班牙语)而不是 Observable Collection。

    【讨论】:

    • 我会多次做这个练习,唯一不同的是源(webservice)和获取数据的异步方式。也许你有样品?很多
    • 你说得对,我的问题是异步调用。但是真的不知道怎么解决。如果您有任何想法,将不胜感激。
    • 嗨 Vasile,第一个选项肯定行不通,但第二个选项就像一个魅力。非常非常tks。
    【解决方案2】:

    我认为视图(xaml 表单)没有通过此绑定了解数据更改。 为什么要使用静态资源? 你可以直接将ListaCapitulos设置为girid的数据源,否则你应该使用MVVM模型,你应该知道你对属性变化的看法。

    【讨论】:

    • 感谢您的帮助,也许是一些样本?
    • 我打算给你发一个样品,但我看到了 Vasile 更新。我觉得没问题。
    • Tks。你是正确的,Vasile 的样本效果很好。非常感谢您的兴趣。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 2012-10-04
    相关资源
    最近更新 更多