Xamarin Forms, Dynamic ScrollView in XAML

Sep 12 2020

Ich möchte eine GUI erstellen, die ähnlich wie der folgende Code ist, eine Bildlaufrolle.

Ich möchte jedoch in der Lage sein, eine Schriftrolle mit dynamischen Inhaltsrahmen zu erstellen, idealerweise in XAML und mit einer Elementquelle gefüllt. Ich denke nicht, dass dies möglich ist, ohne eine benutzerdefinierte Ansicht basierend auf der Elementansicht von dem zu erstellen, was ich sehen kann. ListView und CollectionView machen nicht ganz das, was ich will.

Ich denke, ich muss die Vorschau CarouselView verwenden. Ich habe mich gefragt, ob es eine Möglichkeit gibt, das zu tun, wonach ich suche, ohne.

<?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>

Danke Andy.

Antworten

1 JarvanZhang-MSFT Sep 14 2020 at 15:26

Möchten Sie eine scrollbare Ansicht implementieren und jedes untergeordnete Element enthält mehrere Inhalte, die horizontal gescrollt werden können?

Versuchen Sie für diese Funktion, die CarouselViewin a anzuzeigen ListView.

Überprüfen Sie den Code:

<ListView ...>
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <CarouselView>
                    <CarouselView.ItemTemplate>
                        <DataTemplate>
                            ...
                        </DataTemplate>
                    </CarouselView.ItemTemplate>
                </CarouselView>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Tutorial über CarouselView:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/carouselview/introduction

1 SomeStudent Sep 12 2020 at 10:12

Vorwort: Ich hoffe ich habe deine Anfrage richtig verstanden :)

Wenn Sie unter dynamischem Inhalt eine dynamische ItemTemplate verstehen, können Sie Folgendes versuchen:

Schritt eins:

Definieren Sie einen ItemTemplateSelector. Sie können ihm den gewünschten Namen geben. In dieser Klasse definieren wir, welche Art von Vorlagen wir haben. Nehmen wir an, wir haben die drei, die Sie definiert haben: Gelb, OrangeRot, 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;
       }
   }

Schritt zwei:

Nachdem wir unseren Vorlagen-Selektor definiert haben, können Sie unsere Vorlagen definieren, in diesem Fall unsere Rahmen Yellow, OrangeRed und ForestGreen. Ich werde einfach zeigen, wie man einen von ihnen herstellt, da die anderen dem gleichen Paradigma folgen, wobei sich natürlich die Farbe ändert. Lass uns den YellowFrame machen

In der XAML haben Sie:

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>

Im Code dahinter:

YellowFrame.xaml.cs:

public partial class YellowFrame : StackLayout {
   public YellowFrame() {
      InitializeComponent();
   }
}

Schritt drei

Jetzt müssen wir unser ViewModel erstellen, das wir für unsere ItemSource verwenden, die wir auf FlexLayout anwenden. Gemäß der Dokumentation für bindbare Layouts kann jedes Layout, das "vom Layout abweicht", ein bindbares Layout haben. FlexLayout ist eines davon .

Lassen Sie uns also das ViewModel erstellen. Ich werde auch eine Aufzählung für den Farbrahmen erstellen, den wir rendern möchten, wie ich in der switch-Anweisung in Schritt 1 gezeigt habe. Sie können jedoch auswählen, wie Sie entscheiden möchten, welche Vorlage geladen werden soll. Dies ist nur ein mögliches Beispiel.

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
}

Wir sind fast da. Bisher haben wir unsere Ansichtsmodelle definiert, die wir auf dieser Seite verwenden werden. Der letzte Schritt besteht darin, unsere gesamte XAML zu aktualisieren, in der wir unseren Vorlagen-Selektor aufrufen. Ich werde nur die benötigten Snippets aktualisieren.

<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>

Livebild: