无法在第一个页面加载时从选取器加载数据,但在访问页面时,第二次选取器会按预期加载 [英] cant load data from picker on first page load but when visiting page second time picker loads as expected

查看:118
本文介绍了无法在第一个页面加载时从选取器加载数据,但在访问页面时,第二次选取器会按预期加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我有Xamarin页面,显示产品列表和一个代表产品类型的选取器。 我的问题是,当我第一次启动应用程序并尝试访问页面时,
在调试模式下,我可以看到我正在使用列表,因为ItemsSource具有值 但在加载页面时,选取器将呈灰色显示,并且没有任何数据。
当我用Picker离开页面并再次打开它时,Picker加载了数据!
以下是我的代码!
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         
         xmlns:Converters="clr-namespace:eProdaja.Mobile.Converters"
         mc:Ignorable="d"
         x:Class="Restoran.Mobile.Views.ProizvodiPage">

<ContentPage.Resources>
    <ResourceDictionary>
        <Converters:ImageConverter x:Key="imgConv"></Converters:ImageConverter>
    </ResourceDictionary>
    
</ContentPage.Resources>
<ContentPage.Content>
    <StackLayout>
        <Picker ItemsSource="{Binding TipProizvodaList}"  ItemDisplayBinding="{Binding Naziv}" SelectedItem="{Binding SelectedTipProizvoda}"></Picker>
        <ListView ItemsSource="{Binding ProizvodiList}" ItemSelected="ListView_ItemSelected" >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout  Padding="10" Margin="5" HorizontalOptions="CenterAndExpand" >
                            <Image Source="{Binding Slika, Converter={StaticResource imgConv}}" ></Image>
                            <Label Text="{Binding Naziv}" 
                            d:Text="{Binding .}"
                            LineBreakMode="NoWrap" 
                            Style="{DynamicResource ListItemTextStyle}" 
                            FontSize="16" HorizontalTextAlignment="Center" HorizontalOptions="CenterAndExpand" />
                            <Button  HorizontalOptions="Center" BorderColor="Transparent" BackgroundColor="Transparent" TextColor="OrangeRed" Text="Dodaj u košaricu"></Button>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>



        </ListView>
    </StackLayout>
</ContentPage.Content>

Xaml.cs中的代码
private ProizvodiViewModel model = null;
        public ProizvodiPage()
        {
            InitializeComponent();
            BindingContext = model = new ProizvodiViewModel();
        }

    protected async override void OnAppearing()
    {
        base.OnAppearing();
        await model.Init();
    }

ViewModel中的代码
public ObservableCollection<TipProizvoda> TipProizvodaList { get; set; } = new ObservableCollection<TipProizvoda>();

 public async Task Init()
    {

         if (TipProizvodaList.Count == 0)
        {
            var TPList = await _tipProizvoda.Get<List<TipProizvoda>>(null);
            TipProizvodaList.Clear();
            TipProizvoda empty = new TipProizvoda { TipProizvodaID = 0, Naziv = "" };
            TipProizvodaList.Add(empty);

            foreach (var tipProizvoda in TPList)
            {
                TipProizvodaList.Add(tipProizvoda);
            }
        }
    }

推荐答案

多年来,我尝试在OnAppearing中执行任何影响屏幕显示内容的操作时都遇到各种问题。

必须有Xamarin在On外貌之后执行的操作,以使页面进入有效状态以接收绑定更改。

绕过此限制的一种方法是延迟您要完成的工作,以便OnAppearing在您的工作设置绑定之前返回

这样做的缺点是,该页面将(最初)而不显示您的工作。请参阅对&qot;activityIndicator&的两个引用-在这两个引用中,您可以控制您希望用户在您的工作准备好之前看到的内容。

这样做的好处是它确保了Xamarin&看到您的绑定更改。(如果需要,它还提供了一个进行缓慢后台工作的地方。)

试试:

public partial class MyPage : ...
{
    protected override void OnAppearing()
    {
        base.OnAppearing();

        This returns immediately, allowing OnAppearing to return.
        DelayWork(100, BackgroundWork, UIWork);
    }
    
    // Custom class, used to pass results from background work to UI work.
    class BackgroundResult {
        ...
    }
    
    private void DelayWork(int milliseconds, Func<BackgroundResult> backgroundWork, Action uiWork)
    {
        //OPTIONAL activityIndicator.IsRunning = true;

        Task.Run( () => {
            // The delay ensures Xamarin page preparation has a little time, before your work begins.
            // Without this delay, under some circumstances, the page might not show up as quickly.
            // You might not need this.
            Task.Delay(milliseconds);
            
            // Slow work -- do nothing that affects UI.
            BackgroundResult backgroundResult = BackgroundWork();
            
            Device.BeginInvokeOnMainThread(async () => {
                await uiWork(backgroundResult);
            });
        });
    }

    private BackgroundResult BackgroundWork()
    {
        // Slow work -- do nothing that affects UI.
        ...
        
        // fill this with whatever info you need to pass to UIWork.
        var backgroundResult = new BackgroundResult();
        // ...
        return backgroundResult;
    }

    private async void UIWork(BackgroundResult backgroundResult)
    {
        // Work that affects UI, possibly via Bindings.
        await model.Init();

        //OPTIONAL activityIndicator.IsRunning = false;
    }
}

在您的情况下,您可能不需要BackEarth Work或BackekResult。显示以确保完整性。

这篇关于无法在第一个页面加载时从选取器加载数据,但在访问页面时,第二次选取器会按预期加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆