adospace / reactorui-maui

MauiReactor is a MVU UI framework built on top of .NET MAUI
MIT License
555 stars 46 forks source link

Why doesn't the Image Indicator Template update its source when the Visual State is set to 'Selected'? #151

Closed cris-m closed 10 months ago

cris-m commented 10 months ago

I was trying to work with CarouselView and IndicatorView using image template. IndicatorTemplate doesnot change the Image source when the VisualState is selected.

public class Test 
{
    public string Title { get; set; }
    public string SubTitle { get; set; }
    public string Description { get; set; }
}
class TestPage : Component
{
    public List<Test> tests;
    private MauiControls.CarouselView? _carouselView;
    public TestPage()
    {
        tests = new List<Test>()
        {
            new Test 
            {
                Title = "Lorem Ipsum Dolor Sit Amet",
                SubTitle = "Consectetur Adipiscing Elit",
                Description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in libero non quam accumsan sodales vel vel nunc."
            },
            new Test 
            {
                Title = "Praesent Euismod Tristique",
                SubTitle = "Vestibulum Fringilla Egestas",
                Description = "Praesent euismod tristique vestibulum. Vivamus vestibulum justo in massa aliquam, id facilisis odio feugiat. Duis euismod massa id elit imperdiet."
            },
            new Test 
            {
                Title = "Aliquam Erat Volutpat",
                SubTitle = "Aenean Feugiat In Mollis",
                Description = "Aliquam erat volutpat. Aenean feugiat in mollis ac. Nullam eget justo ut orci dictum auctor."
            },
            new Test 
            {
                Title = "Suspendisse Tincidunt",
                SubTitle = "Faucibus Ligula Quis",
                Description = "Suspendisse tincidunt, arcu eget auctor efficitur, nulla justo tristique neque, et fermentum orci ante eget nunc."
            },
        };
    }
    public override VisualNode Render()
    {
        return new ContentPage 
        {
            new VStack 
            {
                new Grid("* 40", "*")
                {
                    new CarouselView(r => _carouselView = r)
                        .HeightRequest(450)
                        .HorizontalScrollBarVisibility(ScrollBarVisibility.Never)
                        .ItemsSource(tests, _=> new Grid("*", "*")
                        {
                            new VStack 
                            {
                                  new Label(_.Title)
                                    .Margin(0,5)
                                    .TextColor(Themes.Current.OnBackground),
                                  new Label(_.SubTitle)
                                    .Margin(0,5)
                                    .TextColor(Themes.Current.OnBackground),
                                 new Label(_.Description)
                                    .Margin(0,8)
                                    .TextColor(Themes.Current.OnBackground)
                            }
                        })
                        .WithAnimation(),

                    new IndicatorView(r =>
                    {
                        if (_carouselView != null)
                        {
                            _carouselView.IndicatorView = r;
                        }
                    })
                    .HCenter()
                    .VCenter()
                    .IndicatorColor(Colors.Transparent)
                    .SelectedIndicatorColor(Colors.Transparent)
                    .IndicatorTemplate(() => new Image("empty.png").WidthRequest(20).HeightRequest(20))
                    .VisualState("CommonStates", "Normal", MauiControls.Image.SourceProperty, "empty.png")
                    .VisualState("CommonStates", "Selected", MauiControls.Image.SourceProperty, "fill.png")
                    .GridRow(1),
                }
            }
            .Padding(8,0)
            .VCenter()
        }
        .BackgroundColor(Themes.Current.Background);
    }
}

https://github.com/adospace/reactorui-maui/assets/29815096/69c28bba-6d9c-4a62-8adb-1f03018930c6

adospace commented 10 months ago

I verified the issue but it seems to be a .NET MAUI problem: https://github.com/dotnet/maui/issues/13343

adospace commented 10 months ago

anyway, this code should work for you too?

public class TestModel
{
    public string? Title { get; set; }
    public string? SubTitle { get; set; }
    public string? Description { get; set; }
}

class CarouselTestPageWithImagesState
{
    public List<TestModel> Models { get; set; } = new();

    public TestModel? SelectedModel { get; set; }

}

class CarouselTestWithImagesPage : Component<CarouselTestPageWithImagesState>
{
    private MauiControls.CarouselView? _carouselView;

    protected override void OnMounted()
    {
        State.Models = new List<TestModel>()
        {
            new TestModel
            {
                Title = "Lorem Ipsum Dolor Sit Amet",
                SubTitle = "Consectetur Adipiscing Elit",
                Description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in libero non quam accumsan sodales vel vel nunc."
            },
            new TestModel
            {
                Title = "Praesent Euismod Tristique",
                SubTitle = "Vestibulum Fringilla Egestas",
                Description = "Praesent euismod tristique vestibulum. Vivamus vestibulum justo in massa aliquam, id facilisis odio feugiat. Duis euismod massa id elit imperdiet."
            },
            new TestModel
            {
                Title = "Aliquam Erat Volutpat",
                SubTitle = "Aenean Feugiat In Mollis",
                Description = "Aliquam erat volutpat. Aenean feugiat in mollis ac. Nullam eget justo ut orci dictum auctor."
            },
            new TestModel
            {
                Title = "Suspendisse Tincidunt",
                SubTitle = "Faucibus Ligula Quis",
                Description = "Suspendisse tincidunt, arcu eget auctor efficitur, nulla justo tristique neque, et fermentum orci ante eget nunc."
            },
        };

        State.SelectedModel = State.Models.First();

        base.OnMounted();
    }

    public override VisualNode Render()
    {
        return new ContentPage
        {
            new VStack
            {
                new Grid("* 40", "*")
                {
                    new CarouselView(r => _carouselView = r)
                        .HeightRequest(450)
                        .HorizontalScrollBarVisibility(ScrollBarVisibility.Never)
                        .ItemsSource(State.Models, _=> new Grid("*", "*")
                        {
                            new VStack
                            {
                                  new Label(_.Title)
                                    .Margin(0,5),
                                  new Label(_.SubTitle)
                                    .Margin(0,5),
                                 new Label(_.Description)
                                    .Margin(0,8)
                            }
                        })
                        .CurrentItem(() => State.SelectedModel!)
                        .OnCurrentItemChanged((s, args) => SetState(s => s.SelectedModel = (TestModel)args.CurrentItem))
                        ,

                    new HStack(spacing: 5)
                    {
                        State.Models.Select(item => 
                            new Image(State.SelectedModel == item ? "tab_home.png" : "tab_map.png")
                                .WidthRequest(20)
                                .HeightRequest(20)
                                .OnTapped(()=>SetState(s=>s.SelectedModel = item, false))
                            )
                    }
                    .HCenter()
                    .VCenter()
                    .GridRow(1)
                }
            }
            .Padding(8,0)
            .VCenter()
        };
    }
}
cris-m commented 10 months ago

Yeah. it is the perfect solution. Thanks for the help