我有一个Xamarin.Forms应用程序,并且我想在一个页面中使用CarouselView来显示图像列表。
在该页面上,首先向用户显示总体详细信息,因此此时CarouselView不可见(父框架具有绑定道具IsVisible),并且用户可以在两个选项(内部和外部)之间进行选择,以查看图像。点CarouselView现在对用户可见,并且填充ItemsSource的列表中仅包含有关所选选项的图像。
我的xaml和代码工作正常,但问题是,只有在页面加载时显示CarouselView时,它才有效;如果隐藏了CarouselView,则将发生绑定,但是一旦可见,便不会显示任何内容。我尝试了对可见性和绑定到CarouselView的初始数据进行的许多排列,如果隐藏了Carousel,则它们都不起作用。
我不确定这种行为是否与可见性部分或偶然性无关,而只是用于测试是否使CarouselView默认可见,并且隐藏了“详细信息”(与我想要的功能相反),CarouselView可以正常工作。
我考虑的一种选择是使用2个单独的CarouselView,并根据用户的选择显示/隐藏每个。这样做的问题是,我将在下一版本上有更多选择,因此我需要添加多个对象来控制它。
我在主代码外创建了一个简单的应用程序来复制此行为,尽管我在呈现方式上略有不同,但是如果隐藏了CarouselView,则不加载数据的行为仍在继续。
我的页面的XAML:
<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" mc:Ignorable="d" x:Class="carouseltest.Views.ItemsPage" Title="{Binding Title}" x:Name="BrowseItemsPage">
<StackLayout>
<Frame>
<StackLayout>
<Button Text="Overall" Clicked="DisplayChanges_OnClick" CommandParameter="-1"/>
<Button Text="Interior Pictures" Clicked="DisplayChanges_OnClick" CommandParameter="0"/>
<Button Text="Exterior Pictures" Clicked="DisplayChanges_OnClick" CommandParameter="1"/>
</StackLayout>
</Frame>
<Frame IsVisible="{Binding OverallVisible}">
<StackLayout>
<Label Text="{Binding OverallDetails}"/>
</StackLayout>
</Frame>
<Frame IsVisible="{Binding PicturesVisible}">
<CollectionView ItemsSource="{Binding ImagesSelectedOption}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImagePath}"/>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Frame>
</StackLayout>
</ContentPage>
.CS文件
public partial class ItemsPage : ContentPage {
ItemViewModel viewModel;
public ItemsPage() {
InitializeComponent();
BindingContext = viewModel = new ItemViewModel {
OverallDetails = "House For sale 01",
Images = new List<DisplayImages> {
new DisplayImages{ ImagePath = "interior_01", Option=0},
new DisplayImages{ ImagePath = "interior_02", Option=0},
new DisplayImages{ ImagePath = "interior_03", Option=0},
new DisplayImages{ ImagePath = "interior_04", Option=0},
new DisplayImages{ ImagePath = "exterior_01", Option=1},
new DisplayImages{ ImagePath = "exterior_02", Option=1},
new DisplayImages{ ImagePath = "exterior_03", Option=1},
new DisplayImages{ ImagePath = "exterior_04", Option=1}
}
};
}
void DisplayChanges_OnClick(object sender, EventArgs e) {
int selectedValue = -1;
Button button = sender as Button;
int.TryParse(button?.CommandParameter?.ToString(), out selectedValue);
viewModel.overallVisible = selectedValue < 0;
viewModel.SelectedOption = selectedValue;
}
protected override void OnAppearing() {
base.OnAppearing();
}
}
public class ItemViewModel : BaseViewModel {
private int selectedOption = 0;
public int SelectedOption {
get { return selectedOption; }
set {
selectedOption = value;
OnPropertyChanged("OverallVisible");
OnPropertyChanged("PicturesVisible");
OnPropertyChanged("ImagesSelectedOption");
}
}
public bool overallVisible = true;
public bool OverallVisible {
get {
return overallVisible;
}
}
public bool PicturesVisible {
get {
return !overallVisible;
}
}
public string OverallDetails { get; set; }
public List<DisplayImages> Images { get; set; }
private Dictionary<int, List<DisplayImages>> imagesSelectedOption = new Dictionary<int, List<DisplayImages>>();
public List<DisplayImages> ImagesSelectedOption {
get {
var selOpt = selectedOption;
if (!imagesSelectedOption.Keys.Contains(selOpt)) {
List<DisplayImages> displayImages = new List<DisplayImages>();
displayImages.AddRange(Images.Where(c => c.Option == selOpt).ToList());
imagesSelectedOption.Add(selOpt, displayImages);
}
return imagesSelectedOption[selOpt];
}
}
}
public class DisplayImages {
public string ImagePath { get; set; }
public int Option { get; set; }
}
我尝试过的其他方法:
更改具有相同结果的CollectionView的CarouselView。
提前非常感谢您!
编辑:添加显示工作和不工作示例的视图:
https://imgur.com/a/3hQyVoa
编辑2
在@ JuniorJiang-MSFT提出建议后,我使用他的建议更改了示例代码以重新绑定集合,并且我的示例现在正在运行。因此,为了帮助可能从中受益的任何其他人,我在这里添加新代码:
XAML更改-删除了对ItemsSource的出价,为“轮播”添加了名称,因此我可以重新绑定代码:
<ContentPage ...>
<Frame IsVisible="{Binding PicturesVisible}">
<CarouselView x:Name="carousel">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImagePath}"/>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</Frame>
...
</ContentPage>
.CS更改-添加了类级别属性,以便在轮播首次显示时重新绑定轮播,更改了按钮代码以重新绑定课程:
private bool carouselBound = false;
...
void DisplayChanges_OnClick(object sender, EventArgs e) {
int selectedValue = -1;
Button button = sender as Button;
int.TryParse(button?.CommandParameter?.ToString(), out selectedValue);
viewModel.SelectedOption = selectedValue;
if (selectedValue >= 0) {
if (!carouselBound) {
carouselBound = true;
carousel.SetBinding(CarouselView.ItemsSourceProperty, "ImagesSelectedOption");
}
if (carousel.ItemsSource.OfType<object>().Count() > 0)
carousel.ScrollTo(0, animate: false);
}
}
最佳答案
我的xaml和代码工作正常,但问题是,只有在页面加载时显示CarouselView时,它才起作用,如果隐藏了CarouselView,则绑定发生,但是一旦可见,则不显示任何内容。
从这种现象来看,Control从隐藏变为可见,数据模型将不会重新加载。
然后,解决方案应通过重新绑定itemsource重新加载数据。
关于c# - CarouselView仅在加载时可见时显示绑定(bind)项目,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57261784/