Search code examples
c#blazormudblazor

How to run a Method by clicking on MudTabPanel in MudBlazor


I want to manipulate with background-color of Component "MyBox" using Tabs. Background of Component has to be filled with the color, named in Tabs. One condition: you're not allowed to delete @bind-ActivePanelIndex="activeIndex" from code (it's used for other purposes). I have a method "SetColor", but I don't understand how to run it. I'll be thankfull for any help.

Index.razor

<MudTabs Elevation="0" Outlined="true" @bind-ActivePanelIndex="activeIndex">
    <MudTabPanel Text="Red"></MudTabPanel>
    <MudTabPanel Text="Blue"></MudTabPanel>
</MudTabs>

<MyBox colorBox="@colorMe"/>

@code
{
    int activeIndex = 0;
    string colorMe = "";
    
    void SetColor()
    {
        if(activeIndex == 0)
        {
            colorMe = "red";
        } 
        else if(activeIndex == 1)
        {
            colorMe = "blue";
        } 
    }
}

MyBox.razor

<MudItem Style="@($"background-color:{colorBox}; padding:10px; border:1px solid black")">
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eum sit praesentium eos impedit. Est delectus non fugiat perferendis, quos et quis fugit iusto laborum esse voluptates sequi harum quo ab.
</MudItem>

 
@code {
  [Parameter]
  public string colorBox {get; set;}
}

Solution

  • Since you already have the MudTabPanel Text as colors and store the active index of the panel, then we can assign value of color to MyBox by accessing the panel's text by index. This way is better if you are working with a lot of tabs as noted from your comment.

    The MyBox component code remains unchanged and still using @bind-ActivePanelIndex="activeIndex" as required.

    Working example:

    @page "/"
    
    <MudTabs @ref="tabs" Elevation="0" Outlined="true" 
             @bind-ActivePanelIndex="activeIndex">
        <MudTabPanel Text="Red"></MudTabPanel>
        <MudTabPanel Text="Blue"></MudTabPanel>
    </MudTabs>
    
    <MyBox colorBox="@((tabs == null) ? "Red": tabs?.Panels[activeIndex].Text)" />
    
    @code
    {
        private MudTabs? tabs;
        private int activeIndex = 0;
    }
    

    Edit:
    If you want to run the method SetColor as mentioned in your comment, you then have to use ActivePanelIndexChanged to invoke this function whenever the panel index changes and assign the color.

    However, you can't have @bind-ActivePanelIndex="activeIndex" and ActivePanelIndexChanged together in `MudTabs which will give the following error:

    The component parameter 'ActivePanelIndexChanged' is used two or more times for this component.
    

    Therefore, to bind index value to activeIndex, I modified the SetColor method to include a parameter which will pass the index of the panel from ActivePanelIndexChanged EventCallback and assign it to activeIndex.

    <MudTabs Elevation="0" Outlined="true"
            ActivePanelIndexChanged="@(index => SetColor(index))">
       <MudTabPanel Text="Red"></MudTabPanel>
       <MudTabPanel Text="Blue"></MudTabPanel>
    </MudTabs>
    
    <MyBox colorBox="@colorMe" />
    
    @code
    {
       private int activeIndex = 0;
       string colorMe = "red"; // specify default color of first panel
    
       void SetColor(int index)
       {
           activeIndex = index;
    
           if (activeIndex == 0)
           {
               colorMe = "red";
           }
           else if (activeIndex == 1)
           {
               colorMe = "blue";
           }
       }
    }
    

    Result: MudTabs change color on click