Xamarin Forms, Dynamic ScrollView ใน XAML
ฉันต้องการสร้าง GUI ที่คล้ายกับสิ่งที่สร้างโค้ดต่อไปนี้คือการเลื่อนเฟรม
อย่างไรก็ตามฉันต้องการให้มีการเลื่อนของเฟรมเนื้อหาแบบไดนามิกตามหลักการแล้วใน XAML และเติมข้อมูลด้วยแหล่งที่มาของรายการ ฉันไม่คิดว่าสิ่งนี้จะเป็นไปได้หากไม่สร้างมุมมองที่กำหนดเองตามมุมมองรายการจากสิ่งที่ฉันเห็น ListView และ CollectionView ไม่ค่อยทำในสิ่งที่ฉันต้องการ
ฉันคิดว่าฉันต้องใช้ CarouselView ดูตัวอย่างฉันสงสัยว่ามีวิธีทำในสิ่งที่ฉันไม่ต้องการหรือไม่
<?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>
ขอบคุณแอนดี้
คำตอบ
คุณต้องการใช้มุมมองที่เลื่อนได้หรือไม่และเด็กแต่ละคนมีเนื้อหาหลายรายการที่สามารถเลื่อนได้ในแนวนอน?
สำหรับคุณสมบัตินี้ให้ลองแสดงCarouselViewในไฟล์ListView.
ตรวจสอบรหัส:
<ListView ...>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<CarouselView>
<CarouselView.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
บทช่วยสอนเกี่ยวกับ CarouselView:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/carouselview/introduction
คำนำ: ฉันหวังว่าฉันจะเข้าใจคำขอของคุณอย่างถูกต้อง :)
หากตามเนื้อหาแบบไดนามิกคุณหมายถึงการมี ItemTemplate แบบไดนามิกคุณสามารถลองทำสิ่งต่อไปนี้:
ขั้นตอนแรก:
กำหนด ItemTemplateSelector คุณสามารถตั้งชื่อที่คุณต้องการได้ ในคลาสนี้เราจะกำหนดประเภทของเทมเพลตที่เรามีสมมติว่าเรามีสามแบบที่คุณกำหนดไว้: 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;
}
}
ขั้นตอนที่สอง:
ตอนนี้เราได้กำหนด Template Selector ของเราแล้วให้เราดำเนินการต่อและกำหนดเทมเพลตของเราในกรณีนี้เฟรมสีเหลือง OrangeRed และ ForestGreen ของเราตามลำดับ ฉันจะแสดงวิธีสร้างหนึ่งในนั้นเนื่องจากคนอื่น ๆ จะทำตามกระบวนทัศน์เดียวกันยกเว้นโดยแน่นอนว่าสีจะเปลี่ยนไป มาทำ YellowFrame กัน
ใน XAML คุณจะมี:
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>
ในโค้ดด้านหลัง:
YellowFrame.xaml.cs:
public partial class YellowFrame : StackLayout {
public YellowFrame() {
InitializeComponent();
}
}
ขั้นตอนที่สาม
ตอนนี้เราจำเป็นต้องสร้าง ViewModel ของเราที่เราจะใช้สำหรับ ItemSource ของเราที่เราจะนำไปใช้กับ FlexLayout ตามเอกสารสำหรับBindable Layoutsเลย์เอาต์ใด ๆ ที่ "dervies from Layout" มีความสามารถในการมีเค้าโครงที่ผูกมัดได้ FlexLayout ก็เป็นหนึ่งในนั้น .
ดังนั้นให้เราสร้าง ViewModel ฉันจะสร้าง Enum สำหรับกรอบสีที่เราต้องการแสดงผลตามที่ฉันแสดงในคำสั่ง switch ในขั้นตอนที่หนึ่งอย่างไรก็ตามคุณสามารถเลือกวิธีการตัดสินใจได้ว่าจะบอกเทมเพลตใดที่จะโหลดได้อย่างไร นี่เป็นเพียงตัวอย่างหนึ่งที่เป็นไปได้
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
}
เราเกือบจะถึงจุดนั้นแล้วสิ่งที่เราได้ทำไปแล้วคือการกำหนดโมเดลมุมมองของเราที่เราจะใช้ในหน้านั้นขั้นตอนสุดท้ายคือการอัปเดต XAML โดยรวมของเราซึ่งเราจะเรียกตัวเลือกเทมเพลตของเรา ฉันจะอัปเดตเฉพาะส่วนย่อยที่จำเป็นเท่านั้น
<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>
ภาพสด: