MVVM with tabview - updating ContentPage title based on Active Tab

(1) I have a simple ContentPage - how would I update the ContentPage Title on ActiveTab changed? I see the eventtocommand KB here https://www.syncfusion.com/kb/11562/how-to-turn-events-into-commands-with-behaviors-in-xamarin-forms-tabbed-view, but I am not sure how I can get the title or name of the selectedtab from this command so I can update the Title accordingly. Based on which tab is selected, I want to set a different CotentPage title. The selectionChangedEventArgs is always null from the KB link above.



UPDATE: I didn't realize that the behaviors classes were NOT built-in, I added the classes from the link above and it works now. Leaving this part of the question up in case anyone else has the same issue.

(1) Follow up to the above, on the first load of the app, how would I get the Tab Name? Currently, the TabViewSelectionChanged command fires only when the user clicks on different tabs. On first load, I want to set the ContentPage Title, so for that how would I get the Tabs Name?

(2) If I have multiple tabs, say 4, by default the first tab is always selected when the app starts or page navigated to. How can I set the starting tab to be #2 (a middle tab)?

(3) How do I set Padding around the tabview icons/name? Is it possible to set the tabheight to say 100, and justify the icons and name to the top, leaving some room in the bottom. The reason for this is because on the newer iPhones, the tabs attach to the bottom of the screen and it is hard to tab through. Leaving some space at the bottom would help.

(4) Is it possible to set the xaml in a different page and reference it inside the tabview? In the XF standard tab page, I can set the contentPage to a different Page like so:

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestXam.Views.MainPage"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
xmlns:local="clr-namespace:TestXam.Views;assembly=TestXam"
android:TabbedPage.ToolbarPlacement="Bottom" Title="{Binding currentPageName}">

<local:ContentOnePage />
<local:ContentTwoPage />

TabbedPage/>




11 Replies

SP Sakthivel Palaniyappan Syncfusion Team April 23, 2021 12:43 PM UTC

Hi Reza Mohamed,

Greetings from Syncfusion.

Query 1: On the first load of the app, how would I get the Tab Name

We can get he TabItem name by using SelectedIndex property of SfTabView as like below code snippet.

ViewModel:
 
public MainPageViewModel(int selectedIndex) 
{ 
    GetTitleName(selectedIndex); 
}

private
void GetTitleName(int index) 
{ 
   SelectedTabTitle = Items[index].Title; 
} 
 

Query 2 :
How can I set the starting tab to be #2 (a middle tab)?
We can achieve your requirement by setting SelectedIndex property of SfTabview as like below code snippet.

XAML:
 
<tabView:SfTabView  Items="{Binding Items}" VisibleHeaderCount="-1" VerticalOptions="FillAndExpand" x:Name="tabView" SelectedIndex="{Binding TabViewSelectedIndex,Mode=TwoWay}" BackgroundColor="Aqua"> 
</tabView:SfTabView> 
 

ViewModel: 
private int tabViewSelectedIndex = 1; 
  
public int TabViewSelectedIndex 
{ 
    get { return tabViewSelectedIndex; } 
    set 
    { 
        tabViewSelectedIndex = value; 
        NotifyPropertyChanged("TabViewSelectedIndex"); 
    } 
 

Query 3: How do I set Padding around the tabview icons/name? Is it possible to set the tabheight to say 100

We can achieve your requirement by using custom tab header of SfTabView  and setting TabHeight  property of SfTabview as like below code snippet

XAML:
 
<tabView:SfTabView  Items="{Binding Items}" VisibleHeaderCount="-1" TabHeight="100" VerticalOptions="FillAndExpand" x:Name="tabView" SelectedIndex="{Binding TabViewSelectedIndex,Mode=TwoWay}" BackgroundColor="Aqua"> 
</tabView:SfTabView> 
 

ViewModel:
 
public MainPageViewModel(int selectedIndex) 
{ 
    Items = new TabItemCollection(); 
    Label page1Header = new Label(); 
    page1Header.Text = "Page1"; 
    page1Header.Padding = 5; 
    page1Header.HorizontalTextAlignment = TextAlignment.Center; 
    page1Header.VerticalTextAlignment = TextAlignment.Center; 
  
 
  
    Items.Add(new SfTabItem { Content = page1.Content, Title = "Page1", HeaderContent = page1Header }); ; 
    Items.Add(new SfTabItem { Content = page2.Content, Title = "Page2", HeaderContent = page2Header }); 
    Items.Add(new SfTabItem { Content = page3.Content, Title = "Page3", HeaderContent = page3Header }); 
  
    GetTitleName(selectedIndex); 
} 
  
 

Query 4:
Is it possible to set the xaml in a different page and reference it inside the tabview? 
Tab view is a content view control and don’t have support to load page as tab item content. To load the page as tab item content, add tab items with different page content as like below code snippet

ViewModel:
 
public TabItemCollection Items 
{ 
    get { return items; } 
    set 
    { 
        items = value; 
        NotifyPropertyChanged("Items"); 
    } 
} 
  
public MainPageViewModel(int selectedIndex) 
{ 
    Items = new TabItemCollection(); 
  
    TabViewItemPage1 page1 = new TabViewItemPage1(); 
    TabViewItemPage2 page2 = new TabViewItemPage2(); 
    TabViewItemPage3 page3 = new TabViewItemPage3(); 
  
    Items.Add(new SfTabItem { Content = page1.Content, Title = "Page1", HeaderContent = page1Header }); ; 
    Items.Add(new SfTabItem { Content = page2.Content, Title = "Page2", HeaderContent = page2Header }); 
    Items.Add(new SfTabItem { Content = page3.Content, Title = "Page3", HeaderContent = page3Header }); 
} 
 

We have created sample based on your requirement and please find the sample from below.


Sample:
https://www.syncfusion.com/downloads/support/directtrac/general/ze/TabViewCommand-885983614.zip

Please let us know if you have any other queries.

Regards,
Sakthivel P.
 



RE Reza May 5, 2021 07:32 PM UTC

For (3) yes I have set the TabHeight, but my question is more so how I can say justify the image and label in the tab to the top and have some room at the bottom. Just setting the TabHeight seems to always justify the content in the center. Eg. The tab icons and label below have padding on the bottom:
enter image description here

For (4) Is it possible to mix Xaml and C# instead of writing all the XAML in the code behind file? Meaning, I have the following XAML already, it would be very tedious to rewrite all the xaml in code behind, I would like to only attach the Content Page for the tabitem.Content Eg. Grid (Bold and underlined)

<tabView:SfTabView TabHeaderPosition="Bottom" TabHeight="100"
TabHeaderBackgroundColor="{Binding TabBackgroundColor}"
DisplayMode="ImageWithText" VisibleHeaderCount="3" SelectedIndex="{Binding TabViewSelectedIndex, Mode=TwoWay}">

<tabView:SfTabView.Behaviors>
<behaviors:EventToCommandBehavior Command="{Binding SelectionChangedCommand}"
EventName="SelectionChanged" />
tabView:SfTabView.Behaviors>

<tabView:SfTabItem Title="Content1" ImageSource="cheeseburger.png" >
<tabView:SfTabItem.Content>
<Grid BackgroundColor="LightSkyBlue" x:Name="AllContactsGrid">
<ListView ItemsSource="{Binding ClarityCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding Description}">Label>
ViewCell>
DataTemplate>
ListView.ItemTemplate>
ListView>
Grid>
tabView:SfTabItem.Content>
tabView:SfTabItem>

<tabView:SfTabItem Title="Content2" ImageSource="cheeseburger.png">
<tabView:SfTabItem.Content>
<Grid BackgroundColor="LightBlue" x:Name="AllContactsGrid2" />
tabView:SfTabItem.Content>
tabView:SfTabItem>

<tabView:SfTabItem Title="Content3" ImageSource="cheeseburger.png">
<tabView:SfTabItem.Content>
<Grid BackgroundColor="LightGreen" x:Name="AllContactsGrid3" />
tabView:SfTabItem.Content>
tabView:SfTabItem>

tabView:SfTabView>



SP Sakthivel Palaniyappan Syncfusion Team May 7, 2021 02:26 AM UTC

Hi Reza,

Thanks for the update.

We will create sample based on your requirement and update the details on before end of the day Today.

Regards,
Sakthivel P.



RE Reza May 8, 2021 07:48 PM UTC

Just to throw another complication, I'd like to mix it up with Items in codebehind and Xaml with nested TabItems as well. In the case below, Tab1 would be definied in xaml, but Tab2 and 3 would need to have contentpage from code behind. I am defining SubTab1 and SubTab2 in codebehind to test.

<tabView:SfTabView
    TabHeaderPosition="Bottom"
    TabHeight="65"
    VisibleHeaderCount="-1" EnableSwiping="False">
            <!--  Items="{Binding MainTabItems}">  -->
 
 
            <tabView:SfTabView.Behaviors>
                <behaviors:EventToCommandBehavior Command="{Binding SelectionChangedCommand}" EventName="SelectionChanged" />
            </tabView:SfTabView.Behaviors>
 
 
            <tabView:SfTabView.Items>
 
                <tabView:SfTabItem Title="Tab1">
 
                    <tabView:SfTabItem.Content>
 
                        <tabView:SfTabView
                    Items="{Binding ContrastTabItems}"
                    TabHeaderPosition="Top"
                    VisibleHeaderCount="-1" EnableSwiping="False">
 
 
                            <!-- <tabView:SfTabView.Items> -->
                            <!--    -->
                            <!--     <tabView:SfTabItem Title="SubTab1" /> -->
                            <!--     <tabView:SfTabItem Title="SubTab2" /> -->
                            <!--    -->
                            <!-- </tabView:SfTabView.Items> -->
 
                        </tabView:SfTabView>
 
                    </tabView:SfTabItem.Content>
 
                </tabView:SfTabItem>
 
 
                <tabView:SfTabItem Title="Tab2" />
                <tabView:SfTabItem Title="Tab3" />
 
            </tabView:SfTabView.Items>
 
 
        </tabView:SfTabView>


SP Sakthivel Palaniyappan Syncfusion Team May 9, 2021 04:33 PM UTC

Hi Reza,

Thanks for the update.

Query 3: How I can say justify the image and label in the tab to the top and have some room at the bottom

We can achieve your requirement by using custom header of SfTabView as like below code snippet.

XAML:

 
  <tabView:SfTabItem.HeaderContent> 
                <ContentView> 
                    <Grid> 
                        <Grid.RowDefinitions> 
                            <RowDefinition Height="0.1*" /> 
                            <RowDefinition Height="0.1*" /> 
                            <RowDefinition Height="0.1*" /> 
                        </Grid.RowDefinitions> 
 
                        <Label FontFamily="Icons" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Text="&#xe71d;"/> 
                        <Label Text="Tab1" FontSize="12"  Grid.Row="1"  HorizontalTextAlignment="Center"/> 
                    </Grid> 
                </ContentView> 
            </tabView:SfTabItem.HeaderContent> 


Query 4: Is it possible to mix Xaml and C# instead of writing all the XAML and I'd like to mix it up with Items in codebehind and Xaml with nested TabItems as well

We have analyzed your query and we can achieve your requirement as like below code snippet.

XAML:

 
<tabView:SfTabView x:Name="tabView"  VisibleHeaderCount="-1" TabHeight="65" SelectionChanged="tabView_SelectionChanged" TabHeaderPosition="Bottom"> 
        <tabView:SfTabItem> 
            <tabView:SfTabItem.HeaderContent> 
                 
            </tabView:SfTabItem.HeaderContent> 
            <tabView:SfTabItem.Content> 
                <tabView:SfTabView Items="{Binding Items}" VisibleHeaderCount="-1"/> 
            </tabView:SfTabItem.Content> 
        </tabView:SfTabItem> 
    </tabView:SfTabView> 
 

C#:

 
   public partial class MainPage : ContentPage 
    { 
        public MainPage() 
        { 
            InitializeComponent(); 
 
            TabItemPage1 page1 = new TabItemPage1(); 
            TabItemPage2 page2 = new TabItemPage2(); 
 
            tabView.Items.Add(new SfTabItem { Content = page1.Content, HeaderContent = new TabHeader1("\ue71a", "Tab2") }); ; 
            tabView.Items.Add(new SfTabItem { Content = page2.Content, HeaderContent = new TabHeader1("\ue71e", "Tab3") }); 
 
            SetTextColor(tabView, tabView.SelectedIndex); 
 
            BindingContext = new TabViewModel(); 
        } 
} 

We have created sample based on your requirement and please find the sample from below.

Sample:
https://www.syncfusion.com/downloads/support/directtrac/general/ze/TabViewIcon-743070636.zip

Please let us know if you have any other queries.

Regards,
Sakthivel P.
 



RE Reza May 12, 2021 02:55 PM UTC

(4) There is some misunderstanding here, what I am asking is if there is a way to add Items via code behind as well as XAML together. 

Meaning, let's say I have three tabs. I have bound all the Tab Items Content directly via code behind like in your example. Instead, I would like to just bind Tab1 via code behind, but code Tab2 and Tab3 directly in the XAML - commented out below because I wasn't sure how to achieve this.



(5) How can I simply add a line above the TabItems. I dont want to use a fill color, but just a simple line:







SP Sakthivel Palaniyappan Syncfusion Team May 13, 2021 04:09 PM UTC

Hi Reza,

Thanks for the update.

Query 4: Is it possible to mix Xaml and C# instead of writing all the XAML and I'd like to mix it up with Items in codebehind and Xaml with nested TabItems as well

We have analyzed your query and we can achieve your requirement as like below code snippet.

XAML:

 
<tabView:SfTabView x:Name="tabView"  VisibleHeaderCount="-1" TabHeight="65" SelectionChanged="tabView_SelectionChanged" TabHeaderPosition="Bottom"> 
        <tabView:SfTabItem> 
            <tabView:SfTabItem.Content> 
                <tabView:SfTabView x:Name="nestedTab" VisibleHeaderCount="-1"> 
                    <tabView:SfTabItem Title="SubTab2"> 
                        <tabView:SfTabItem.Content> 
                            <local:SecondView/> 
                        </tabView:SfTabItem.Content> 
                    </tabView:SfTabItem> 
                    <tabView:SfTabItem Title="SubTab3"> 
                        <tabView:SfTabItem.Content> 
                            <local:THirdView/> 
                        </tabView:SfTabItem.Content> 
                    </tabView:SfTabItem> 
                </tabView:SfTabView> 
            </tabView:SfTabItem.Content> 
        </tabView:SfTabItem>
</
tabView:SfTabView> 


C#:

 
  public MainPage() 
        { 
            TabItemPage1 page1 = new TabItemPage1(); 
            InitializeComponent(); 
            nestedTab.Items.Insert(0, (new SfTabItem { Content = page1.Content, Title = "SubTab1" })); 
 
                    } 

Query 5:  How can I simply add a line above the TabItems. I dont want to use a fill color, but just a simple line

We can achieve your requirement by using Custom header as like below code snippet.

 
            <tabView:SfTabItem.HeaderContent> 
                
                    <Grid> 
                        <Grid.RowDefinitions> 
                            <RowDefinition Height="Auto" /> 
 
                            <RowDefinition Height="0.1*" /> 
                            <RowDefinition Height="0.1*" /> 
                            <RowDefinition Height="0.1*" /> 
                        </Grid.RowDefinitions> 
                        <Grid HeightRequest="1" BackgroundColor="LightGray"/> 
                        <Label FontFamily="Icons" Grid.Row="1" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" Text="&#xe71d;"/> 
                        <Label Text="Tab1" FontSize="12"  Grid.Row="2"  HorizontalTextAlignment="Center"/> 
                    </Grid> 
                
            </tabView:SfTabItem.HeaderContent> 

Screenshot:


Please find the sample from below link,

Sample:

https://www.syncfusion.com/downloads/support/directtrac/general/ze/TabViewIcon229375663.zip

Please let us know if you have any other queries.

Regards,
Sakthivel P.
 



RE Reza May 13, 2021 05:33 PM UTC

for (4) you are using codebehind in the example, I am looking for the MVVM approach.

for (5) I get that you are creating a custom tab, but I would like to keep the default ImageAndText, but just have a line above with no fill color for the tabs

<tabView:SfTabItem
    Title="Step"
    FontIconFontColor="{StaticResource Gray-400}"
    FontIconFontFamily="FontIcons"
    FontIconFontSize="Small"
    IconFont="{StaticResource Icon2}"
    SelectionColor="{StaticResource Gray-600}"
    TitleFontColor="{StaticResource Gray-400}"
    TitleFontSize="Micro" 
    TitleFontFamily="Font-Regular"/>


KG Kanimozhi Gunasekaran Syncfusion Team May 14, 2021 01:04 PM UTC

Hi Reza Mohamed,

Query 4: You are using code behind in the example, I am looking for the MVVM approach.

As per your requirement we have modified the sample.

Code snippet: 
        public TabViewModel(SfTabView tabView) 
       
            SetItems(); 
            sfTabView = tabView; 
            sfTabView.Items.Insert(0, (new SfTabItem { Content = page1.Content, Title = "SubTab1" })); 
       


Query 5: I get that you are creating a custom tab, but I would like to keep the default ImageAndText, but just have a line above with no fill color for the tabs

We have analyzed your requirement in SfTabView. We don’t have the support for provide the line when using the TabItem title. But we have achieved by sample level. Line provided for the bottom of the TabItem content. We have modified the same in sample.

Code snippet: 
            <tabView:SfTabItem.Content> 
                <Grid> 
                    <Grid.RowDefinitions> 
                        <RowDefinition Height="*"/> 
                        <RowDefinition Height="1"/> 
                    </Grid.RowDefinitions> 
                    <tabView:SfTabView x:Name="nestedTab" VisibleHeaderCount="-1"> 
                    <tabView:SfTabItem Title="SubTab2"> 
                        <tabView:SfTabItem.Content> 
                            <local:SecondView/> 
                        </tabView:SfTabItem.Content> 
                    </tabView:SfTabItem> 
                    <tabView:SfTabItem Title="SubTab3"> 
                        <tabView:SfTabItem.Content> 
                            <local:THirdView/> 
                        </tabView:SfTabItem.Content> 
                    </tabView:SfTabItem> 
                </tabView:SfTabView> 
                    <Grid HeightRequest="1" Grid.Row="1" BackgroundColor="LightGray"/> 
                </Grid> 
            </tabView:SfTabItem.Content> 


Sample Link:
https://www.syncfusion.com/downloads/support/directtrac/general/ze/TabViewIcon90417867

Please check with above sample and let us know if you have any concern on this.

Regards,
Kanimozhi G.  




RE Reza May 26, 2021 01:35 AM UTC

how can I add this line on a TOP tab bar, with the Grey line on the bottom of the tabs using codebehind? This is my current code to add the Subtab/content pages.

ContrastContent Content1 = new ContrastContent();
ClarityContent Content2 = new ClarityContent();
 
 
ContrastTabItems = new TabItemCollection()
  {
      new SfTabItem()
      {
          Title = "Contrast",
          Content = Content1.Content,
          TitleFontFamily = "Font-Regular",
           TitleFontColor = ResourceHelpers.GetColorFromResourceKey("Gray-400"),
           TitleFontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
          SelectionColor = ResourceHelpers.GetColorFromResourceKey("Gray-600")
 
      },
      new SfTabItem()
      {
          Title = "Clarity",
          Content = Content2.Content,
          TitleFontFamily = "Font-Regular",
          TitleFontColor = ResourceHelpers.GetColorFromResourceKey("Gray-400"),
          TitleFontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
          SelectionColor = ResourceHelpers.GetColorFromResourceKey("Gray-600")
      }
  };

So in this case, the red line below would be the 'grey line'



Also just to add a twist, the content inside Content1 and Content2 is (because of the blue button in the picture) so if I do something like this in code, the AbsoluteLayout get messed up, as you can see from the picture below.

            Grid content1 = new Grid()
   {
       RowDefinitions =
        {
            new RowDefinition {Height = new GridLength(1)},
            new RowDefinition {Height = new GridLength(1, GridUnitType.Star)}
        }
   };
 
 
   Grid.SetRow(contrastContent, 1);
 
 
   content1.Children.Add(new BoxView()
   {
       BackgroundColor = Color.Red,
       HeightRequest = 1
   });
 
 
   content1.Children.Add(contrastContent.Content);
 
 
   ContrastTabItems = new TabItemCollection()
     {
         new SfTabItem()
         {
             Title = "Contrast",
             Content = content1,
             TitleFontFamily = "Font-Regular",
              TitleFontColor = ResourceHelpers.GetColorFromResourceKey("Gray-400"),
              TitleFontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label)),
             SelectionColor = ResourceHelpers.GetColorFromResourceKey("Gray-600")
 
},








SS Suganya Sethuraman Syncfusion Team May 27, 2021 02:04 PM UTC

HI Reza,

Thanks for the update.

We have analyzed your query and checked the reported issue as per your provided code snippet, but we were unable to reproduce the issue. We have added Grid based on your provided code snippet. Please find the code snippet from below.

C#:

 
public class TabViewModel  
     
        private TabItemCollection subTabItems;  
  
        public TabItemCollection SubTabItems  
         
            get { return subTabItems; }  
            set  
             
                subTabItems = value;  
             
         
  
        public TabViewModel()  
         
            SetItems();  
            SubTabItems = new TabItemCollection();  
            SubTabItems.Add(new SfTabItem { Content = SetTabItemContent(new TabItemPage1().Content), Title = "Contrast" });  
            SubTabItems.Add(new SfTabItem { Content = SetTabItemContent(new TabItemPage1().Content), Title = "Clarity" });  
        }

 
 
        private Grid SetTabItemContent(View tabItemContent)  
         
            Grid mainGrid = new Grid();  
  
            Grid content1 = new Grid()  
             
                RowDefinitions =  
         
            new RowDefinition {Height = new GridLength(1)},  
            new RowDefinition {Height = new GridLength(1, GridUnitType.Star)}  
         
            };  
  
            Grid.SetRow(tabItemContent, 1);  
  
            content1.Children.Add(new BoxView()  
             
                BackgroundColor = Color.Green,  
                HeightRequest = 1  
            });  
  
            content1.Children.Add(tabItemContent);  
  
            AbsoluteLayout absoluteLayout = new AbsoluteLayout  
             
                Margin = new Thickness(20)  
            };  
  
            absoluteLayout.Children.Add(new Button  
             
                BackgroundColor = Color.Red,  
            }, new Rectangle(250, 300, 60, 60));  
  
            Grid.SetRow(absoluteLayout, 0);  
            mainGrid.Children.Add(content1);  
            mainGrid.Children.Add(absoluteLayout);  
  
            return mainGrid;  
         
 

Please find the sample from below.
 
Sample:
https://www.syncfusion.com/downloads/support/directtrac/general/ze/TabViewIcon-320444131

We suggest you to try our sample and if you are still facing the same issue, please revert us with the reported issue.
 
 
Regards,
Suganya Sethuraman.
 
 


Loader.
Up arrow icon