简体   繁体   中英

How do you reference a parent DataTemplates parameter inside an ItemTemplateSelector located inside of a Bindable StackLayouts?

This sounds like a mouthful but I have a BindableLayout.ItemTemplateSelector that is located inside of a DataTemplate . The problem is I can not pass a property of the DataTemplate 's ItemSource for some reason.

In section 'Data Template' , of 'The Code' below, I am trying to access properties inside of ItemSource="{Binding CarouselItems}" from within <controls:ThoughtEntryDataTemplateSelector> . However, I can't access anything inside of there except for StaticResource 's.

I'd like to pass a property from CarouselItems into it

The Code

Data Template

                    <cards:CarouselView
                        x:Name="ThoughtCarouselViewer"
                        IndicatorView="indicatorView"
                        IsCyclical="False"
                        ItemsSource="{Binding CarouselItems}">
                        <cards:CarouselView.ItemTemplate>
                            <DataTemplate>
                                <StackLayout>
                                    <Label
                                        x:Name="Title"
                                        FontAttributes="Bold"
                                        Text="{Binding Header}"
                                        TextColor="{StaticResource TextColor}" />
                                    <rv:MaterialFrame
                                        Padding="5"
                                        LightThemeBackgroundColor="#F1F1F1"
                                        Style="{StaticResource CardView}">
                                        <StackLayout BindableLayout.ItemsSource="{Binding Source={RelativeSource AncestorType={x:Type local:ThoughtRecordViewModel}}, Path=ThoughtEntryContainers}" Orientation="Vertical">
                                            <BindableLayout.ItemTemplateSelector>
                                                <controls:ThoughtEntryDataTemplateSelector
                                                    ChallengingThought="{StaticResource ChallengingThought}"
                                                    Distortions="{StaticResource Distortions}"
                                                    NegativeThought="{StaticResource NegativeThought}"
                                                    ThoughtType="{Binding ThoughtEntryType}" /> <============================== What I am trying to access
                                            </BindableLayout.ItemTemplateSelector>
                                        </StackLayout>
                                    </rv:MaterialFrame>
                                </StackLayout>
                            </DataTemplate>
                        </cards:CarouselView.ItemTemplate>
                    </cards:CarouselView>

DataTemplateSelector

    public class ThoughtEntryDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate NegativeThought { get; set; }
        public DataTemplate Distortions { get; set; }
        public DataTemplate ChallengingThought { get; set; }
        public ThoughtEntryType ThoughtType { get; set; }

        protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
        {
            DataTemplate dataTemplate;

            if(ThoughtType == ThoughtEntryType.NegativeThought)
            {
                dataTemplate = NegativeThought;
            } else if(ThoughtType == ThoughtEntryType.Distortion)
            {
                dataTemplate = Distortions;
            } else
            {
                dataTemplate = ChallengingThought;
            }

            return dataTemplate;
        }
    }

Carousel Items

    public class ThoughtEntryCarouselItems
    {
        private string header;
        public string Header
        {
            get => header;
            set => header = value;
        }

        private ThoughtEntryType thoughtEntryType;
        public ThoughtEntryType ThoughtEntryType
        {
            get => thoughtEntryType;
            set => thoughtEntryType = value;
        }
    }

According to Creating a Xamarin.Forms DataTemplateSelector , I suggest you can choose a DataTemplate for CarouselView, not for StackLayout, then you can get current item ThoughtEntryType in OnSelectTemplate method, please see my code.

 <ContentPage.Resources>
    <DataTemplate x:Key="ChallengingThought">
        <StackLayout >
            <Label FontAttributes="Bold" Text="{Binding Header}" />
            <Frame CornerRadius="30" BorderColor="Black" BackgroundColor="AliceBlue">
                <StackLayout BindableLayout.ItemsSource="{Binding EntryContainers}" Orientation="Vertical">
                    <Label Text="{Binding .}" />
                </StackLayout>
            </Frame>
        </StackLayout>
    </DataTemplate>
    <DataTemplate x:Key="NegativeThought" >
        <StackLayout>
            <Label FontAttributes="Bold" Text="{Binding Header}" />
            <Frame  CornerRadius="30" BorderColor="Black" BackgroundColor="DarkGray">
                <StackLayout BindableLayout.ItemsSource="{Binding EntryContainers}" Orientation="Vertical">
                    <Label Text="{Binding .}" />
                </StackLayout>
            </Frame>
        </StackLayout>
    </DataTemplate>
    <DataTemplate x:Key="Distortions">
        <StackLayout >
            <Label FontAttributes="Bold" Text="{Binding Header}" />
            <Frame CornerRadius="30" BorderColor="Black" BackgroundColor="YellowGreen">
                <StackLayout BindableLayout.ItemsSource="{Binding EntryContainers}" Orientation="Vertical">
                    <Label Text="{Binding .}" />
                </StackLayout>
            </Frame>
        </StackLayout>
    </DataTemplate>
    <local:ThoughtEntryDataTemplateSelector x:Key="EntryDataTemplateSelector"
            ChallengingThought="{StaticResource ChallengingThought}"
                                                Distortions="{StaticResource Distortions}"
                                                NegativeThought="{StaticResource NegativeThought}"/>
</ContentPage.Resources>
<ContentPage.Content>
    <StackLayout>
        <CarouselView
                    x:Name="ThoughtCarouselViewer"                                          
                    ItemsSource="{Binding CarouselItems}" ItemTemplate="{StaticResource EntryDataTemplateSelector}">

        </CarouselView>
    </StackLayout>
</ContentPage.Content>

 public partial class Page24 : ContentPage
{
    public Page24()
    {
        InitializeComponent();
        this.BindingContext = new ThoughtRecordViewModel();
    }
}
public class ThoughtRecordViewModel
{
    public ObservableCollection<ThoughtEntryCarouselItems> CarouselItems { get; set; }
    public ThoughtRecordViewModel()
    {
        CarouselItems = new ObservableCollection<ThoughtEntryCarouselItems>()
        {
            new ThoughtEntryCarouselItems(){Header="header 1",EntryType=ThoughtEntryType.ChallengingThought,EntryContainers=new ObservableCollection<string>(){"1","2","3"}},
            new ThoughtEntryCarouselItems(){Header="header 2",EntryType=ThoughtEntryType.Distortions,EntryContainers=new ObservableCollection<string>(){"a","b","c"}},
            new ThoughtEntryCarouselItems(){Header="header 3",EntryType=ThoughtEntryType.NegativeThought,EntryContainers=new ObservableCollection<string>(){"11","22","33"}},
            new ThoughtEntryCarouselItems(){Header="header 4",EntryType=ThoughtEntryType.ChallengingThought,EntryContainers=new ObservableCollection<string>(){"112","2222","3333"}},

        };
    }
}

public class ThoughtEntryCarouselItems
{
    private string header;
    public string Header
    {
        get => header;
        set => header = value;
    }

    private ThoughtEntryType _EntryType;
    public ThoughtEntryType EntryType
    {
        get => _EntryType;
        set => _EntryType = value;
    }

    public ObservableCollection<string> EntryContainers { get; set; }
}
public enum ThoughtEntryType
{
    NegativeThought, Distortions, ChallengingThought
}
public class ThoughtEntryDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate NegativeThought { get; set; }
    public DataTemplate Distortions { get; set; }
    public DataTemplate ChallengingThought { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        DataTemplate dataTemplate=null;
        ThoughtEntryCarouselItems carouseitem = (ThoughtEntryCarouselItems)item;

        if (carouseitem.EntryType == ThoughtEntryType.NegativeThought)
        {
            dataTemplate = NegativeThought;
        }
        else if (carouseitem.EntryType == ThoughtEntryType.Distortions)
        {
            dataTemplate = Distortions;
        }
        else if(carouseitem.EntryType == ThoughtEntryType.ChallengingThought)
        {
            dataTemplate = ChallengingThought;
        }
        return dataTemplate;

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM