【发布时间】:2020-06-04 17:06:06
【问题描述】:
场景是,内容页面打开时显示多个图像的轮播。
这些图像被绑定为ImageSource 的可观察集合,它们很好
当页面显示时,我可以看到轮播是空的。
我尝试了两种不同的 CarouselView。 xamarin brings by default 的一个和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 的评论和 repo,我更新了它以反映我遇到的问题并设法重现它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 会破坏事情,但只在第一次加载时才会被选为正确答案。
【问题讨论】:
-
您是否尝试过像这样设置图像的纵横比:
Aspect="AspectFill" -
我认为不是 CarouselView 引起的,可能是您的项目有问题。我写了一个示例项目here,它可以工作。你能分享给我们a Minimal, Reproducible Example吗?
-
您的示例是从文件中添加图像,而不是从流中添加图像,我现在怀疑这与问题有关。稍后我可以使用您的示例并对其进行调整以使用流中的图像。谢谢你的时间!很快就会更新 3。
-
添加了更新 3 和最小的可重现示例。
-
发现问题了!请参阅更新 4。希望你们能告诉我为什么..