Xamarin Forms, XAML의 동적 ScrollView
다음 코드가 생성하는 프레임 스크롤과 유사한 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을 갖는 것을 의미하는 경우 다음을 시도 할 수 있습니다.
1 단계 :
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;
}
}
2 단계 :
이제 템플릿 선택기를 정의 했으므로 템플릿을 정의하겠습니다.이 경우에는 각각 Yellow, 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();
}
}
3 단계
이제 Bindable Layouts에 대한 문서에 따라 FlexLayout에 적용 할 ItemSource에 사용할 ViewModel을 만들어야 합니다. "Layout에서 파생 된"레이아웃은 Bindable 레이아웃을 가질 수 있고 FlexLayout이 그중 하나입니다. .
이제 ViewModel을 만들어 보겠습니다. 1 단계의 switch 문에서 보여준 것처럼 렌더링하려는 Color 프레임에 대한 Enum도 만들겠습니다. 그러나로드 할 템플릿을 지정하는 방법을 결정하는 방법을 선택할 수 있습니다. 이것은 하나의 가능한 예일뿐입니다.
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>
라이브 사진 :