Use a DataTempleSelector to change the DataTemplate that is currently displayed in a CarouselView?

MarkDailMarkDail USMember ✭✭
edited September 2016 in Xamarin.Forms

I am working on an app that one section of it displays Flash Cards for studying certain subjects. What I tried to set up was a DataTemplateSelector that changed the DataTemplate depending on whether a Flipped property was true or false. Then I used a button to change the Flipped property. What I have found is that when the Flipped property is changed the DataTemplateSelector does not even fire. Also as the Flipped property is not displayed anywhere, there is no way for me to set the Binding to 2-way. Which means that if I scroll to the next card and back the Flipped is set to false still so the DataTemplate is still the same template it was the first time. Also there is no way to change the DataTemplate in code as it is part of the ResourceDictionary which means I can not reference it in code because the code doesn't see it. Even if I give it a x:Name property the code still doesn't see it. Does anyone have any Idea how I can achieve changing the current view to the other DataTemplate? Oh and I did try making the property fire a PropertyChanged event and that made know difference.

For reference the DataTemplate is written in XAML. The XAML part of the DataTemplateSelector looks like this, I am not including the Templates them selves as the two together are very long, if anyone wants to see what they look like please just let me know:

            <pdg:CarouselTemplateSelector x:Key="carouselTemplateSelector"
                    QuestionTemplate="{StaticResource questionTemplate}"
                    AnswerTemplate="{StaticResource answerTemplate}" />

The code part of the DataTemplateSelector looks like this:

    class CarouselTemplateSelector : DataTemplateSelector
        {
            private string tag = "CarouselTemplateSelector";

            public CarouselTemplateSelector()
            {
                WriteLine(tag + ", CarouselTemplateSelector constructor");

            }
            public DataTemplate QuestionTemplate
            {
                get; set;
            }
            public DataTemplate AnswerTemplate
            {
                get; set;
            }

            protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
            {
                Questions question = (Questions)item;
                if(!question.Flipped)
                {
                    return QuestionTemplate;
                }
                else
                {
                    return AnswerTemplate;
                }
            }        
        }

The CarouselView looks like this:

        <cv:CarouselView ItemsSource="{Binding Source={x:Static pdg:App.QuestionsList}}"
                     ItemTemplate="{StaticResource carouselTemplateSelector}"
                     PositionSelected="OnPositionSelected"
                     x:Name="FlashCards"
                      RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, 
                                                  Property=Width, Factor=0.006}"
                      RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
                                                 Property=Height, Factor=0.010}"
                      RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, 
                                                      Property=Width, Factor=0.986}"
                      RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, 
                                                      Property=Height, Factor=0.890}"  />

Any help or ideas would be greatly appreciated. If anyone wants to see some of the other code, either XAML or C# just let me know. Thanks

Answers

  • JulienRosenJulienRosen CAMember ✭✭✭✭

    The template selector is only called when the item is first drawn to the screen. It doesn't know anything about your custom properties.

    As a quick fix, you could remove and re-insert the item. I'm sure there is a better way of accomplishing this though.

  • MarkDailMarkDail USMember ✭✭

    I'll give that a try an see if it fixes the problem, thanks for your quick response.

  • MarkDailMarkDail USMember ✭✭

    Any idea the best way to accomplish removing and re-inserting the item? Does the fact that it's a CarouselView make a difference of how to accomplish that?

  • GaetanFGaetanF USMember ✭✭✭

    You can't do that with the DataTemplateSelector because as @JulienRosen said, it get called only once per item when first drawn. Actually, you have to embed the different presentations inside the View and manage which presentation is displayed dynamically through bindings. Forget about the DataTemplateSelector in this case.

    Source

Sign In or Register to comment.