Xamarin Forms, Dynamic ScrollView in XAML
Voglio creare una GUI che abbia un simile a quello che genera il codice seguente, uno scorrimento di frame.
Tuttavia, voglio essere in grado di avere uno scorrimento di frame di contenuto dinamico, idealmente in XAML e popolato con un'origine elemento. Non penso che ciò sia possibile senza creare una visualizzazione personalizzata basata su itemsview da ciò che posso vedere. ListView e CollectionView non fanno esattamente quello che voglio.
Penso di aver bisogno di usare l'anteprima CarouselView, mi chiedevo se c'è un modo per fare quello che cerco senza.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FlexTest.MainPage">
<ContentPage.Resources>
<Style TargetType="Frame">
<Setter Property="WidthRequest" Value="300"/>
<Setter Property="HeightRequest" Value="500"/>
<Setter Property="Margin" Value="10"/>
<Setter Property="CornerRadius" Value="20"/>
</Style>
</ContentPage.Resources>
<ScrollView Orientation="Both">
<FlexLayout>
<Frame BackgroundColor="Yellow">
<FlexLayout Direction="Column">
<Label Text="Panel 1"/>
<Label Text="A Panel"/>
<Button Text="Click Me"/>
</FlexLayout>
</Frame>
<Frame BackgroundColor="OrangeRed">
<FlexLayout Direction="Column">
<Label Text="Panel 2"/>
<Label Text="Another Panel"/>
<Button Text="Click Me"/>
</FlexLayout>
</Frame>
<Frame BackgroundColor="ForestGreen">
<FlexLayout Direction="Column">
<Label Text="Panel 3"/>
<Label Text="A Third Panel"/>
<Button Text="Click Me"/>
</FlexLayout>
</Frame>
</FlexLayout>
</ScrollView>
</ContentPage>
Grazie Andy.
Risposte
Vuoi implementare una visualizzazione scorrevole e ogni bambino contiene più contenuti che possono essere fatti scorrere orizzontalmente?
Per questa funzione, prova a visualizzare CarouselViewin a ListView.
Controlla il codice:
<ListView ...>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<CarouselView>
<CarouselView.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Tutorial su CarouselView:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/carouselview/introduction
Prefazione: spero di aver capito correttamente la tua richiesta :)
Se per contenuto dinamico intendi avere un ItemTemplate dinamico, puoi provare a fare quanto segue:
Primo passo:
Definisci un ItemTemplateSelector, puoi dargli il nome che desideri. In questa classe definiremo che tipo di template abbiamo, diciamo di avere i tre che hai definito: Yellow, OrangeRed, ForestGreen
public class FrameTemplateSelector : DataTemplateSelector {
public DataTemplate YellowFrameTemplate {get; set;}
public DataTemplate OrangeRedFrameTemplate {get; set;}
public DataTemplate ForestGreenFrameTemplate {get; set;}
public FrameTemplateSelector() {
this.YellowFrameTemplate = new DataTemplate(typeof (YellowFrame));
this.OrangeRedFrameTemplate = new DataTemplate(typeof (OrangeRedFrame));
this.ForestGreenFrameTemplate = new DataTemplate(typeof (ForestGreenFrame));
}
//This part is important, this is how we know which template to select.
protected override DataTemplate OnSelectTemplate(object item, BindableObject container) {
var model = item as YourViewModel;
switch(model.FrameColor) {
case FrameColorEnum .Yellow:
return YellowFrameTemplate;
case FrameColorEnum .OrangeRed:
return OrangeRedFrameTemplate;
case FrameColorEnum .ForestGreen:
return ForestGreenFrameTemplate;
default:
//or w.e other template you want.
return YellowFrameTemplate;
}
}
Passo due:
Ora che abbiamo definito il nostro selettore di modelli, andiamo avanti e definiamo i nostri modelli, in questo caso rispettivamente i nostri fotogrammi Yellow, OrangeRed e ForestGreen. Mostrerò semplicemente come realizzarne uno poiché gli altri seguiranno lo stesso paradigma escludendo, con ovviamente il cambio di colore. Facciamo il YellowFrame
In XAML avrai:
YellowFrame.xaml:
<StackLayout 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="YourNameSpaceGoesHere.YellowFrame">
<Frame BackgroundColor="Yellow">
<FlexLayout Direction="Column">
<Label Text="Panel 1"/>
<Label Text="A Panel"/>
<Button Text="Click Me"/>
</FlexLayout>
</Frame>
</StackLayout>
Nel codice dietro:
YellowFrame.xaml.cs:
public partial class YellowFrame : StackLayout {
public YellowFrame() {
InitializeComponent();
}
}
Fase tre
Ora dobbiamo creare il nostro ViewModel che useremo per il nostro ItemSource che applicheremo a FlexLayout, secondo la documentazione per Bindable Layouts , qualsiasi layout che "dervies from Layout" ha la capacità di avere un Bindable Layout, FlexLayout è uno di questi .
Quindi creiamo il ViewModel, creerò anche un Enum per il frame Color che vogliamo rendere come ho mostrato nell'istruzione switch nel passaggio uno, tuttavia, puoi scegliere cosa significa decidere come dire quale modello caricare; questo è solo un possibile esempio.
BaseViewModel.cs:
public abstract class BaseViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = ""){
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public virtual void CleanUp(){
}
}
ParentViewModel.cs:
public class ParentViewModel: BaseViewModel {
private ObservableCollection<YourViewModel> myViewModels {get; set;}
public ObservableCollection<YourViewModel> MyViewModels {
get { return myViewModels;}
set {
myViewModels = value;
OnPropertyChanged("MyViewModels");
}
}
public ParentViewModel() {
LoadData();
}
private void LoadData() {
//Let us populate our data here.
myViewModels = new ObservableCollection<YourViewModel>();
myViewModels.Add(new YourViewModel {FrameColor = FrameColorEnum .Yellow});
myViewModels.Add(new YourViewModel {FrameColor = FrameColorEnum .OrangeRed});
myViewModels.Add(new YourViewModel {FrameColor = FrameColorEnum .ForestGreen});
MyViewModels = myViewModels;
}
}
YourViewModel.cs:
public class YourViewModel : BaseViewModel {
public FrameColorEnum FrameColor {get; set;}
}
FrameColorEnum.cs:
public enum FrameColorEnum {
Yellow,
OrangeRed,
ForestGreen
}
Ci siamo quasi, quindi quello che abbiamo fatto finora è aver definito i nostri modelli di visualizzazione che useremo in quella pagina, il passaggio finale è aggiornare il nostro XAML generale dove chiameremo il nostro selettore di modelli. Aggiornerò solo gli snippet necessari.
<ContentPage
...
**xmlns:views="your namespace where it was defined here,
normally you can just type the name of the Selector then have VS add the proper
namespace and everything"**
<ContentPage.Resources>
<!--New stuff below-->
<ResourceDictionary>
<views:FrameTemplateSelector x:Key="FrameTemplateSelector"/>
</ResourceDictionary>
</ContentPage.Resources>
<ScrollView Orientation="Both">
<FlexLayout BindableLayout.ItemsSource="{Binding MyViewModels, Mode=TwoWay}"
BindableLayout.ItemTemplateSelector ="{StaticResource FrameTemplateSelector}"/>
</ScrollView>
Immagine dal vivo: