图片在第一次加载时未显示在 CarouselView 中

Images not shown in CarouselView on first load

场景是,内容页面打开时带有显示多张图片的轮播。 这些图像被绑定为 ImageSource 的可观察集合,它们很好 当页面显示时,我可以看到轮播是空的。

我试过两种不同的 CarouselView。 xamarin brings by default and the one from CardsView nuget 库。两者的结果是一样的。

该页面显示的轮播视图没有图像,但有适量的项目(即:我可以看到可观察集合有 3 个项目)。

我怀疑这一定是某种竞争条件,因为一旦我在调试时强制热重新加载视图(即:我保存 XAML 并且视图在设备中重新加载)我可以查看图片正确显示的轮播。

为了重现它,我还在旋转木马之外单独添加了图像,以证明它们在那里。 我还在视图中添加了两个轮播。这是第一次加载的结果:

在我保存 xaml 之后(根本没有对其进行任何操作)并且视图刷新,这就是我所看到的,并且是正确的。

请注意,在第一次加载时,这 3 个图像如何在轮播外正确显示,但在任何轮播内都没有显示,尽管 如果我在轮播中添加的是文本则没有问题.

知道问题出在哪里吗?这是赛车状态吗?还是两个不同的轮播都有问题?

这是我的代码

<?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:viewModels="clr-namespace:Sasw.AforoPass.ViewModels;assembly=Sasw.AforoPass"
             xmlns:panCardView="clr-namespace:PanCardView;assembly=PanCardView"
             xmlns:controls="clr-namespace:PanCardView.Controls;assembly=PanCardView"
             mc:Ignorable="d"
             x:Class="Sasw.AforoPass.Views.MainPage" 
             x:DataType="viewModels:MainViewModel">
    <ContentPage.Content>
        <StackLayout>
            <StackLayout.Resources>
                <ResourceDictionary>
                    <ResourceDictionary.MergedDictionaries>
                        <ResourceDictionary Source="/Styles/Styles.xaml" />
                    </ResourceDictionary.MergedDictionaries>
                </ResourceDictionary>
            </StackLayout.Resources>

            <CarouselView BackgroundColor="White"
                          x:Name="Carousel"
                          ItemsSource="{Binding Images}">
                <CarouselView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout 
                            HorizontalOptions="CenterAndExpand" 
                            VerticalOptions="CenterAndExpand">
                            <Image Source="{Binding .}"></Image>
                            <Label Text="image should be here"></Label>
                        </StackLayout>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>


            <panCardView:CarouselView 
                ItemsSource="{Binding Images}"
                BackgroundColor="{StaticResource ColorPrimary}"
                HorizontalOptions="FillAndExpand"
                VerticalOptions="FillAndExpand">
                <panCardView:CarouselView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout 
                            HorizontalOptions="CenterAndExpand" 
                            VerticalOptions="CenterAndExpand">
                            <Image Source="{Binding .}"></Image>
                            <Label Text="image should be here"></Label>
                        </StackLayout>
                    </DataTemplate>
                </panCardView:CarouselView.ItemTemplate>

                <controls:LeftArrowControl />
                <controls:RightArrowControl />
                <controls:IndicatorsControl ToFadeDuration="1500"/>
            </panCardView:CarouselView>
            <Image WidthRequest="20" HeightRequest="20" Source ="{Binding Images[0]}"></Image>
            <Image WidthRequest="20" HeightRequest="20"  Source ="{Binding Images[1]}"></Image>
            <Image WidthRequest="20" HeightRequest="20"  Source ="{Binding Images[2]}"></Image>

            <Button Text="Close"></Button>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

集合范围是:

public ObservableCollection<ImageSource> Images
{
    get => _images;
    set
    {
        _images = value;
        OnPropertyChanged();
    }
}

更新 1: 我刚刚编辑了整个问题,因为起初我认为问题可能与 Rg.Plugins.Popup 有关,因为它发生在弹出窗口中。但是我在正常的内容页面上也试过了,问题依然存在,所以这肯定是轮播的问题。


更新 2 我继续调查。到目前为止,问题似乎出在轮播中的图像流上,无论是 Xamarin 轮播还是 CardView 的库轮播(它们具有不同的机制)。

我试过向访问流的图像添加选项和高度和宽度请求,但没有成功

<!--in DataTemplate within the carousel-->
<Image Source="{Binding .}" HeightRequest="100"
   WidthRequest="100"
   VerticalOptions="FillAndExpand" 
   HorizontalOptions="FillAndExpand"></Image>
<Label Text="image should be here"></Label>

更新 3:

感谢 Jack Hua 的评论和回购,我更新了它以反映我遇到的问题并设法重现它 at this specific commit here

基本上我采用了相同的 repo,添加了一个 QRCoder 库以在运行时快速生成图像 byte[] 并添加了来自流的图像源。

public Model() {

    Images = new ObservableCollection<ImageSource>();

    var imageOne = GetQrImageAsBytes();
    var imageTwo = GetQrImageAsBytes();
    var imageThree = GetQrImageAsBytes();

    // This works
    //Images.Add(ImageSource.FromFile("logo.jpg"));
    //Images.Add(ImageSource.FromFile("sample.jpg"));
    //Images.Add(ImageSource.FromFile("ttt.png"));

    Images.Add(ImageSource.FromStream(() => new MemoryStream(imageOne)));
    Images.Add(ImageSource.FromStream(() => new MemoryStream(imageTwo)));
    Images.Add(ImageSource.FromStream(() => new MemoryStream(imageThree)));
}

private byte[] GetQrImageAsBytes()
{
    var randomText = Guid.NewGuid().ToString();
    var qrGenerator = new QRCodeGenerator();
    var qrCodeData = qrGenerator.CreateQrCode(randomText, QRCodeGenerator.ECCLevel.L);
    var qRCode = new PngByteQRCode(qrCodeData);
    var qrCodeBytes = qRCode.GetGraphic(20);
    return qrCodeBytes;
}

更新 4:

我发现了问题,我不得不尝试几次以确保这确实是问题所在,但确实如此。

Re-Sharper 建议我对 ItemsSource="{Binding Images}" 进行更改,因为它无法识别 Images。所以我遵循 Re-Sharper 的建议,让它在 xaml 的 ContentPage 标签中添加一个 x:DataType="app265:Model"。这导致了问题。我真的不知道为什么,但今晚我会睡得更好:)

<?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:app265="clr-namespace:App265;assembly=App265"
             mc:Ignorable="d"
             x:Class="App265.MainPage" 
             x:DataType="app265:Model"><!--this line that Re-Sharper adds causes the issue-->

这是 Xamarin 错误吗?或者它对你有意义吗? 解释为什么这个 x:DataType 会破坏东西但只在第一次加载时会被选为正确答案。

x:DataType="ImageSource"

将此添加到轮播视图 DataTemplate。它应该可以解决您的问题。 BindignContext检测似乎有些问题,所以你应该"help"自己检测它。

xamarin.forms 5.0.0.2012 也有同样的问题,但在我的例子中,我的图像源是 url。它在轮播视图 DataTemplate

中与 x:DataType="x:String" 一起使用
<CarouselView
        ItemsSource="{Binding ImageSources}"
        >
        <CarouselView.ItemTemplate>
            <DataTemplate
                x:DataType="x:String">
                <forms:CachedImage
                    Aspect="AspectFit"
                    ErrorPlaceholder="Placeholder"
                    LoadingPlaceholder="Placeholder"
                    DownsampleWidth="300"
                    DownsampleToViewSize="True"
                    Source="{Binding .}">