Maui Filter Content based on button, update UI

366 Views Asked by At

I'm trying to filter the content based on some buttons like this

enter image description here

I have the XAML setup as this

        <CollectionView Grid.Row="0"
                    ItemsSource="{Binding Categories}" 
                    ItemsLayout="HorizontalList"
                    Margin="20,0"
                    x:Name="els">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="x:String">
                <Button Style="{StaticResource ButtonOutline}" Text="{Binding .}" FontSize="20" Margin="5,10"
                        Clicked="CategorySelected"/>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>

And my Page has the following method for the event, the idea is to change the style of the button that was clicked

private void CategorySelected(object sender, EventArgs e)
{
    var btn = (Button)sender;
    btn.TextColor = Color.Parse("#FFFFFF");
    viewModel.ChangeCategory(btn.Text);     
}

Everything is working as expected, but I can't seem to find a way to change the style of all the other buttons that weren't clicked. How can I have access to them? I have access to the CollectionView in my code, but I'm not able to access the Children variable that I can in debug mode (after going to base multiple times), I've tried all types of casting, but no success

enter image description here

Is there a way to reach those children? Or maybe another solution that is more MVVM like

2

There are 2 best solutions below

0
On

If someone has the same issue, I would advise to checkout this project on Github, he solves this perfectly maui-starbucks-ui

2
On
  1. Styling on its own is enough to achieve this, for example by setting the VisualStates.

  2. You are trying to make a RadioGroup with RadioButtons. You can just use those controls. (But I get the idea that you are practicing, I recognize this code)

  3. DataTriggers can be used to change the appearance of your controls. Combined with some Value Convertors you can get this job done.

  4. I would recommend also using SelectedItem of CollectionView. However, right now there are some pretty serious bugs regarding horizontal CollectionView. (Forget about spacing) As well as bugs about disabling/enabling and changing the visual state.

My code is full with "//TODO: Fix when github issue link is resolved." So I do not advise you to put too much effort right now. Make it tappable and move on.

Edit: About your question, check this for example:

<RadioButton Content="{Binding .}">
<RadioButton.ControlTemplate>
    <ControlTemplate>
        <Grid RowDefinitions="30,4">
            <Label Text="{TemplateBinding Content}" />
            <BoxView Grid.Row="1" Color="Transparent"/>
        </Grid>
    </ControlTemplate>
</RadioButton.ControlTemplate>

And to make it change style:

<ControlTemplate>
<Grid RowDefinitions="30,4">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroupList>
            <VisualStateGroup x:Name="CheckedStates">
                <VisualState x:Name="Checked">
                    <VisualState.Setters>
                        <Setter
                            TargetName="TextLabel"
                            Property="Label.TextColor"
                            Value="{StaticResource Primary}"/>
                        <Setter
                            TargetName="Indicator"
                            Property="BoxView.Color"
                            Value="{StaticResource Primary}"/>
                    </VisualState.Setters>
                </VisualState>

                <VisualState x:Name="Unchecked">
                    <VisualState.Setters>
                        <Setter
                            TargetName="TextLabel"
                            Property="Label.TextColor"
                            Value="White"/>
                        <Setter
                            TargetName="Indicator"
                            Property="BoxView.Color"
                            Value="Transparent"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </VisualStateManager.VisualStateGroups>
    <Label Text="{TemplateBinding Content}" x:Name="TextLabel" />
    <BoxView x:Name="Indicator" Grid.Row="1" Color="Transparent"/>
</Grid>

This is from here:

https://dev.to/davidortinau/making-a-tabbar-or-segmentedcontrol-in-net-maui-54ha

Extremely useful example about making your own controls. I recommend going over everything in that blog.