color connverter

Eduardo Gomez 4,316 Reputation points
2025-07-01T20:56:04.42+00:00

I have a converter

public class SelectedAvatarMultiValueConverter : IMultiValueConverter {

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        if(values.Length == 2 &&
            values[0] is AvatarCharacter current &&
            values[1] is AvatarCharacter selected) {

            return Equals(current, selected) ? Colors.Red : Colors.Transparent;
        }

        return Colors.Transparent;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
        throw new NotImplementedException();
    }
}

This converter, will change the color of the stroke of the avatar to red. This will make it easier for you to know who is selected

 <CollectionView
     ItemsSource="{Binding AvatarCharacters}"
     SelectedItem="{Binding SelectedAvatar}"
     SelectionChangedCommand="{Binding AvatarSelectedCommand}"
     SelectionMode="Single">
     <CollectionView.ItemsLayout>
         <GridItemsLayout
             Orientation="Vertical"
             Span="3" />
     </CollectionView.ItemsLayout>

     <CollectionView.ItemTemplate>
         <DataTemplate x:DataType="sfavatar:AvatarCharacter">
             <Grid Padding="10">
                 <Border
                     HeightRequest="60"
                     StrokeThickness="3"
                     WidthRequest="60">

                     <Border.StrokeShape>
                         <RoundRectangle CornerRadius="30" />
                     </Border.StrokeShape>


                     <Border.Stroke>
                         <MultiBinding Converter="{StaticResource AvatarEqualityConverter}">
                             <Binding Path="." />
                             <Binding
                                 Path="BindingContext.SelectedAvatar"
                                 Source="{x:Reference AppShellFireChatPage}" />
                         </MultiBinding>
                     </Border.Stroke>


This is my entire shell

<Shell
    x:Class="FireChat.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:controls="clr-namespace:FireChat.Controls"
    xmlns:icons="clr-namespace:FireChat.Icons"
    xmlns:local="clr-namespace:FireChat"
    xmlns:model="clr-namespace:FireChat.Model"
    xmlns:sfPopup="clr-namespace:Syncfusion.Maui.Popup;assembly=Syncfusion.Maui.Popup"
    xmlns:sfavatar="clr-namespace:Syncfusion.Maui.Core;assembly=Syncfusion.Maui.Core"
    xmlns:shimmer="clr-namespace:Syncfusion.Maui.Shimmer;assembly=Syncfusion.Maui.Core"
    xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
    xmlns:views="clr-namespace:FireChat.Views"
    xmlns:vm="clr-namespace:FireChat.ViewModels"
    x:Name="AppShellFireChatPage"
    x:DataType="vm:AppShellViewModel"
    FlyoutBehavior="{OnIdiom Desktop=Locked,
                             Phone=Disabled}"
    Shell.FlyoutWidth="60">

    <Shell.Resources>
        <ResourceDictionary>
            <local:SelectedAvatarMultiValueConverter x:Key="AvatarEqualityConverter" />
        </ResourceDictionary>
    </Shell.Resources>

    <ShellContent
        ContentTemplate="{DataTemplate views:WelcomePage}"
        FlyoutItemIsVisible="False"
        Route="WelcomePage"
        Shell.FlyoutBehavior="Disabled"
        Shell.NavBarIsVisible="False" />

    <ShellContent
        ContentTemplate="{DataTemplate views:LoginPage}"
        FlyoutItemIsVisible="False"
        Route="LoginPage"
        Shell.FlyoutBehavior="Disabled"
        Shell.NavBarIsVisible="False" />

    <ShellContent
        ContentTemplate="{DataTemplate views:ChatPage}"
        Route="ChatPage"
        Shell.NavBarIsVisible="{OnIdiom Desktop=False,
                                        Phone=True}">
        <ShellContent.Icon>
            <FontImageSource
                FontFamily="MaterialSymbol"
                Glyph="{Static icons:MateriallFontGlyphs.Chat}"
                Color="{AppThemeBinding Dark={DynamicResource White},
                                        Light={DynamicResource PrimaryDarkText}}" />
        </ShellContent.Icon>
    </ShellContent>

    <Shell.FlyoutFooter>
        <Grid
            Padding="10"
            BackgroundColor="Transparent"
            HeightRequest="48">
            <Image x:Name="UserProfileImage">
                <Image.Source>
                    <FontImageSource
                        FontFamily="MaterialSymbol"
                        Glyph="{Static icons:MateriallFontGlyphs.Account_circle}"
                        Color="{AppThemeBinding Dark={DynamicResource White},
                                                Light={DynamicResource PrimaryDarkText}}" />
                </Image.Source>
                <Image.GestureRecognizers>
                    <TapGestureRecognizer
                        x:DataType="vm:AppShellViewModel"
                        Command="{Binding OpenProfileCommand}" />
                </Image.GestureRecognizers>
            </Image>

            <sfPopup:SfPopup
                x:Name="AvatarOptionsPopUp"
                AbsoluteY="-18"
                Style="{DynamicResource AvatarOptionsPopupStyle}">
                <sfPopup:SfPopup.ContentTemplate>
                    <DataTemplate x:DataType="vm:AppShellViewModel">
                        <CollectionView
                            x:Name="OptionCollectionView"
                            Margin="10"
                            ItemsSource="{Binding OptionsColletion}"
                            SelectedItem="{Binding SelectedItem}"
                            SelectionMode="Single">
                            <CollectionView.ItemTemplate>
                                <DataTemplate x:DataType="model:UserAvatarOptions">
                                    <VerticalStackLayout>
                                        <Label
                                            Padding="10"
                                            Text="{Binding Name}"
                                            VerticalTextAlignment="Center" />
                                        <BoxView
                                            BackgroundColor="{AppThemeBinding Dark={DynamicResource White},
                                                                              Light={DynamicResource PrimaryDarkText}}"
                                            HeightRequest="1"
                                            IsVisible="{Binding IsFirst}" />
                                        <VerticalStackLayout.GestureRecognizers>
                                            <TapGestureRecognizer
                                                x:DataType="vm:AppShellViewModel"
                                                Command="{Binding SelectedOptionCommand, Source={RelativeSource AncestorType={x:Type vm:AppShellViewModel}}}" />
                                        </VerticalStackLayout.GestureRecognizers>
                                    </VerticalStackLayout>
                                </DataTemplate>
                            </CollectionView.ItemTemplate>
                        </CollectionView>
                    </DataTemplate>
                </sfPopup:SfPopup.ContentTemplate>
            </sfPopup:SfPopup>

            <!--  User profile popup  -->

            <sfPopup:SfPopup
                x:Name="UserProfilePopup"
                AbsoluteY="30"
                AcceptCommand="{Binding SavePopUpContentCommand}"
                HeaderHeight="90"
                RelativeView="{x:Reference UserProfileImage}"
                Style="{DynamicResource UserProfilePopupStyle}">

                <sfPopup:SfPopup.Behaviors>
                    <toolkit:EventToCommandBehavior
                        BindingContext="{Binding BindingContext, Source={x:Reference UserProfilePopup}, x:DataType=sfPopup:SfPopup}"
                        Command="{Binding SavePopUpContentCommand}"
                        EventName="Closed" />
                </sfPopup:SfPopup.Behaviors>


                <sfPopup:SfPopup.ContentTemplate>
                    <DataTemplate x:DataType="vm:AppShellViewModel">

                        <Grid
                            Margin="20"
                            RowDefinitions="80,80,80,*">

                            <sfavatar:SfAvatarView
                                x:Name="AvatarImage"
                                Margin="0,0,0,24"
                                AvatarCharacter="{Binding User.AvatarCharacter}"
                                Style="{DynamicResource AvatarStyle}">
                                <sfavatar:SfAvatarView.GestureRecognizers>
                                    <PointerGestureRecognizer
                                        PointerEntered="AvatarPointerGeture_PointerEntered"
                                        PointerExited="AvatarPointerGeture_PointerExited" />
                                    <TapGestureRecognizer Tapped="AvatarTapGesture_Tapped" />
                                </sfavatar:SfAvatarView.GestureRecognizers>
                            </sfavatar:SfAvatarView>

                            <controls:MaterialEntry
                                Grid.Row="1"
                                x:DataType="vm:AppShellViewModel"
                                Hint="Username"
                                ShowIcon="False"
                                Text="{Binding User.Username}" />

                            <controls:MaterialEntry
                                Grid.Row="2"
                                x:DataType="vm:AppShellViewModel"
                                Hint="Status"
                                ShowIcon="False"
                                Text="{Binding User.StatusMessage}" />

                            <Border
                                Grid.Row="3"
                                Margin="0,0,0,20"
                                HorizontalOptions="End"
                                StrokeShape="RoundRectangle 10"
                                StrokeThickness="2"
                                VerticalOptions="End"
                                WidthRequest="100">

                                <Button
                                    Command="{Binding SignOutCommand}"
                                    Style="{StaticResource LogoutButtonStyle}" />
                            </Border>
                        </Grid>
                    </DataTemplate>
                </sfPopup:SfPopup.ContentTemplate>
            </sfPopup:SfPopup>

            <!--  Avatar Selection Popup  -->
            <sfPopup:SfPopup
                x:Name="AvatarSeletionPopUp"
                AbsoluteX="90"
                AbsoluteY="-350"
                HeightRequest="400"
                RelativePosition="AlignTopRight"
                RelativeView="{Reference AvatarOptionsPopUp}"
                ShowHeader="False"
                ShowOverlayAlways="False"
                WidthRequest="300">

                <sfPopup:SfPopup.PopupStyle>
                    <sfPopup:PopupStyle
                        CornerRadius="8"
                        HasShadow="True"
                        PopupBackground="{AppThemeBinding Dark={DynamicResource PrimaryDarkText},
                                                          Light={DynamicResource White}}" />
                </sfPopup:SfPopup.PopupStyle>

                <sfPopup:SfPopup.ContentTemplate>
                    <DataTemplate x:DataType="vm:AppShellViewModel">
                        <CollectionView
                            ItemsSource="{Binding AvatarCharacters}"
                            SelectedItem="{Binding SelectedAvatar}"
                            SelectionChangedCommand="{Binding AvatarSelectedCommand}"
                            SelectionMode="Single">
                            <CollectionView.ItemsLayout>
                                <GridItemsLayout
                                    Orientation="Vertical"
                                    Span="3" />
                            </CollectionView.ItemsLayout>

                            <CollectionView.ItemTemplate>
                                <DataTemplate x:DataType="sfavatar:AvatarCharacter">
                                    <Grid Padding="10">
                                        <Border
                                            HeightRequest="60"
                                            StrokeThickness="3"
                                            WidthRequest="60">

                                            <Border.StrokeShape>
                                                <RoundRectangle CornerRadius="30" />
                                            </Border.StrokeShape>


                                            <Border.Stroke>
                                                <MultiBinding Converter="{StaticResource AvatarEqualityConverter}">
                                                    <Binding Path="." />
                                                    <Binding
                                                        Path="BindingContext.SelectedAvatar"
                                                        Source="{x:Reference AppShellFireChatPage}" />
                                                </MultiBinding>
                                            </Border.Stroke>

                                            <sfavatar:SfAvatarView
                                                AvatarCharacter="{Binding .}"
                                                BackgroundColor="White"
                                                ContentType="AvatarCharacter"
                                                CornerRadius="25"
                                                HeightRequest="50"
                                                WidthRequest="50" />
                                        </Border>
                                    </Grid>
                                </DataTemplate>
                            </CollectionView.ItemTemplate>

                        </CollectionView>
                    </DataTemplate>
                </sfPopup:SfPopup.ContentTemplate>
            </sfPopup:SfPopup>

        </Grid>
    </Shell.FlyoutFooter>
</Shell>


but for some reason is not working

Untitledvideo-MadewithClipchamp-ezgif.com-video-to-gif-converter

Developer technologies | .NET | .NET Multi-platform App UI

Answer accepted by question author
Anonymous
2025-08-04T08:43:05.5833333+00:00

Hello,

After troubleshooting in the comment section, it was confirmed that the SelectedAvatarMultiValueConverter was functioning correctly. However, it consistently received null values during execution. This behavior may be attributed to a binding lifecycle timing mismatch, where UI controls attempt to establish bindings before asynchronous data becomes available.

Migrating from .NET MAUI's CollectionView to Syncfusion's ListView appears to have resolved the issue.

It is likely that .NET MAUI's CollectionView instantiated item templates and evaluated bindings before the asynchronous data (e.g., SelectedAvatar) was loaded and assigned to the view model or individual AvatarCharacter objects.

In contrast, Syncfusion's ListView likely ensures that, by the time the SelectedAvatarMultiValueConverter is invoked for an item, all necessary bound properties—including those previously null—have already been populated from the view model.

I hope this helps clarify the issue.

References

Was this answer helpful?

0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.