Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Color changing of SfTabItem header images #79

Open
DavidV1603 opened this issue Feb 7, 2025 · 3 comments
Open

[Feature Request] Color changing of SfTabItem header images #79

DavidV1603 opened this issue Feb 7, 2025 · 3 comments

Comments

@DavidV1603
Copy link

DavidV1603 commented Feb 7, 2025

Description

I would like to be able to change the color of the Image in the header of an SfTabItem. It is possible to change the color of the text, if HeaderDisplayMode="Text", but if Images are used, different images have to be used.

In other parts of my app, I change the color of SVG-Images using the MAUI community toolkits IconTintColorBehavior. Maybe the same logic can be applied or adding behaviors to the image of the SfTabItem can be added.

Public API Changes

<tabView:SfTabView HeaderDisplayMode="Image">
    <tabView:SfTabItem ImageSource="test.svg" ImageColor="Grey"/>
</tabView:SfTabView>

Other possibility:

<tabView:SfTabView HeaderDisplayMode="Image">
    <tabView:SfTabItem ImageSource="test.svg">
        <tabView:SfTabItem.Behaviors>
            <toolkit:IconTintColorBehavior TintColor="Grey" />
        </tabView:SfTabItem.Behaviors>
    </tabView:SfTabItem>
</tabView:SfTabView>

Intended Use-Case

In my app, I use the SfTabView with SVG images as header to have the same UI in multiple languages. To enhance the visibility of the currently active tab, I added VisualStateGroup, that colors the inactive tab's image grey, while the active tab has a white image. With the text header, this is easily possible by changing the TextColor, but for Image headers, I need multiple, different colored SVGs. This adds unnecessary size to the app, because every icon needs to be added multiple times.

@DavidV1603 DavidV1603 changed the title Color changing of SfTabView header images [Feature Request] Color changing of SfTabView header images Feb 7, 2025
@DavidV1603 DavidV1603 changed the title [Feature Request] Color changing of SfTabView header images [Feature Request] Color changing of SfTabItem header images Feb 7, 2025
@naveenkumar-sanjeevirayan
Copy link
Collaborator

Hi DavidV1603,

Thank you for reaching out with your feature request regarding the ability to change the color of the image in the header of a TabItem. Currently, TabItem does not support modifying the image color based on the selected state.

To meet your requirements, we recommend using FontImageSource in combination with VisualStateManager to update the tab icon color dynamically based on its selection state. Below is an example implementation:

<ContentPage.Resources>
   <Style TargetType="tabView:SfTabItem">
       <Setter Property="VisualStateManager.VisualStateGroups">
           <VisualStateGroupList>
               <VisualStateGroup>
                   <VisualState x:Name="Normal" >
                        <VisualState.Setters>
                           <Setter Property="TextColor" Value="Brown" />
                        </VisualState.Setters>
                   </VisualState>
                   <VisualState x:Name="Selected">
                        <VisualState.Setters>
                           <Setter Property="TextColor" Value="Green" />
                        </VisualState.Setters>
                   </VisualState>
               </VisualStateGroup>
           </VisualStateGroupList>
       </Setter>
   </Style>
</ContentPage.Resources>
 
<tabView:SfTabView x:Name="tabView" HeaderDisplayMode="Image">
   <tabView:SfTabView.Items>
       <tabView:SfTabItemx:Name="callItem">
            <tabView:SfTabItem.ImageSource>
               <FontImageSource Glyph="&#xfeb6;" x:Name="call"
                                Color="{Binding Source={x:Reference callItem},Path=TextColor}"
                             FontFamily="MaterialDesignIcons"/>
            </tabView:SfTabItem.ImageSource>
       </tabView:SfTabItem>
 
   </tabView:SfTabView.Items>
</tabView:SfTabView>

This approach allows you to dynamically adjust the icon color without needing multiple image files.

For your reference, we have attached a sample project demonstrating this implementation. Please review the sample and let us know if you need any further assistance.

Additionally, we have considered your request as a feature enhancement, and we will explore adding direct support for image color modification in any one of our future releases of the Syncfusion MAUI Toolkit.

Thanks,

@DavidV1603
Copy link
Author

Hello naveenkumar-sanjeevirayan,

thank you for your detailled answer. Can you tell me what sample you mean exactly, because I don't see any link here.

If I see it correctly, you approach only works, if you use a Iconfont for your images, and then you could simply just add this as a text anyways. When using SVG files, this does not work, or did I miss something?

If I didn't overlook something, your approach would be the same as using HeaderDisplayMode="Text" and just adding the text there. The suggestion just transforms the glyph into an image internally.

Thank you again for your fast answer and for considering my request.

@naveenkumar-sanjeevirayan
Copy link
Collaborator

Hi DavidV1603,

We apologize for the confusion regarding the sample in our previous update. Please ignore that statement.

Currently, changing the image color based on the selected state in the TabView is not directly supported. However, you can achieve this behavior using the HeaderItemTemplate property along with IconTintColorBehavior. This approach allows you to dynamically update the image color when a tab is selected.

Model

public class Model : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler? PropertyChanged;
 
   protected void OnPropertyChanged(string propertyName)
   {
       var handler = PropertyChanged;
       if (handler != null)
           handler(this, new PropertyChangedEventArgs(propertyName));
   }

   private string? image;
   public string? ImageName
   {
       get { return image; }
       set
       {
           image = value;
            OnPropertyChanged("ImageName");
       }
   }

   private Color? selectedColor;
   public Color? SelectedColor
   {
       get => selectedColor;
       set
       {
           selectedColor = value;
            OnPropertyChanged(nameof(SelectedColor));
       }
   }
}

ViewModel

public class TabItemsSourceViewModel : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler? PropertyChanged;
 
   protected void OnPropertyChanged(string propertyName)
   {
       var handler = PropertyChanged;
       if (handler != null)
           handler(this, new PropertyChangedEventArgs(propertyName));
   }
 
   private ObservableCollection<Model>? tabItems;
   public ObservableCollection<Model>? TabItems
   {
       get { return tabItems; }
       set
       {
           tabItems = value;
            OnPropertyChanged("TabItems");
       }
   }

   public TabItemsSourceViewModel()
   {
       TabItems = new ObservableCollection<Model>();
       TabItems.Add(new Model() { ImageName="call.png", SelectedColor=Colors.Red });
       TabItems.Add(new Model() { ImageName = "contacts.png", SelectedColor = Colors.Gray });
       TabItems.Add(new Model() { ImageName = "favorite.png", SelectedColor = Colors.Gray });
   }
}

XAML

<tabView:SfTabView ItemsSource="{Binding TabItems}" SelectionChanged="OnSelectionChanged">
   <tabView:SfTabView.HeaderItemTemplate>
       <DataTemplate >
           <HorizontalStackLayout Margin="20,0,20,0">
               <Image Source="{Binding ImageName}" Aspect="AspectFit" HorizontalOptions="Center"
                       HeightRequest="40" WidthRequest="40">
                   <Image.Behaviors>
                        <toolkit:IconTintColorBehavior TintColor="{Binding SelectedColor}" />
                   </Image.Behaviors>
               </Image>
           </HorizontalStackLayout>
       </DataTemplate>
    </tabView:SfTabView.HeaderItemTemplate>
 
  <!--ContentItemTemplate-->
 
</tabView:SfTabView>

C#

private void OnSelectionChanged(object sender, TabSelectionChangedEventArgs e)
{
   if (e.NewIndex >= 0 && e.OldIndex>=0)
   {
        viewModel.TabItems[e.OldIndex].SelectedColor = Colors.Gray;
        viewModel.TabItems[e.NewIndex].SelectedColor = Colors.Red;
   }
}

With the use of the SelectionChanged event, the image color will dynamically update based on the old and new index arguments using IconTintColorBehavior. This ensures that the UI reflects the correct selected state as the user switches between tabs.

Please try this solution and let us know if you need further assistance.

Thanks,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants