0

I'm starting with Blazor, checking a simple example of how to implement Cascading Parameters.

I'm trying to use a class and send it as Cascading parameter, the class has two params and one method to change both values.

If I use it in the parent, everything works fine, but if I tried to call the method to change the values, works in the child component, but not in the parent.

I assume should be related that the parent component needs to call the method StateHasChanged(); but I cannot access it through the class.

There is the code of the components:

Parent

<div style="border: 5px solid; border-radius: 10px; padding: 10px; margin: 5px">
    <h2>
        Level 1
    </h2>

    <div>
        Counter: <code>@cascadingClass.Counter</code>.
        <input type="button" value="Call method 'AddOne()'" @onclick="cascadingClass.AddOne"/>
    </div>
    <div>
        Message: <code>@cascadingClass.Message</code>.
    </div>
    <div>
        <CascadingValue Value="@cascadingClass" Name="CascadingClassParam">
            <CascadingParametersLevel2/>
        </CascadingValue>
    </div>
</div>

@code
{
    CascadingClass cascadingClass = new CascadingClass();

    public class CascadingClass
    {
        public int Counter { get; set; }
        public string Message { get; set; }

        public CascadingClass()
        {
            Counter = 50;
            Message = "Initialized";
        }

        public void AddOne()
        {
            Counter++;
            Message = "Value changed!";
        }
    }
}

Child

@using static blazor_training.Client.Shared.Playground.CascadingParametersLevel1

<div style="border: 3px solid; border-radius: 10px; padding: 10px; margin: 5px">
    <h2>
        Level 2
    </h2>
    <div>
        Counter @cascadingClass.Counter <input type="button" value="+1" @onclick="addOne"/>
    </div>
    <div>
        Message: @cascadingClass.Message
    </div>
</div>

@code {

    [CascadingParameter(Name = "CascadingClassParam")]
    protected CascadingClass cascadingClass { get; set; }

    private void addOne()
    {
        cascadingClass.AddOne();
    }

}

Actual behavior

Blazor example

So, I'm missing something important about the good practices of the Blazor Cascading Params? Or there is an easier way to achieve this?

My answer

The question was marked as duplicate, anyway, I left my answer / fix

Parent

<div style="border: 5px solid; border-radius: 10px; padding: 10px; margin: 5px">
    <h2>
        Level 1
    </h2>

    <div>
        Counter: <code>@cascadingClass.Counter</code>.
        <input
            type="button"
            value="Call method 'AddOne()'"
            @onclick="cascadingClass.AddOne"/>
    </div>
    <div>
        Message: <code>@cascadingClass.Message</code>.
    </div>
    <div>
        <CascadingValue Value="@cascadingClass" Name="CascadingClassParam">
            <CascadingParametersLevel2/>
        </CascadingValue>
    </div>
</div>

@code
{
    private CascadingClass cascadingClass;

    protected override void OnInitialized()
    {
        cascadingClass = new CascadingClass(this.StateHasChanged);
    }

    public class CascadingClass
    {
        public int Counter { get; private set; }
        public string Message { get; private set; }
        private Action _refreshParent;

        public CascadingClass(Action stateHasChanged)
        {
            Counter = 50;
            Message = "Initialized";
            _refreshParent = stateHasChanged;
        }

        public void AddOne()
        {
            Counter++;
            Message = "Value changed!";
            _refreshParent();
        }
    }
}

Child

@using static blazor_training.Client.Shared.Playground.CascadingParametersLevel1

<div style="border: 3px solid; border-radius: 10px; padding: 10px; margin: 5px">
    <h2>
        Level 2
    </h2>
    <div>
        Counter @cascadingClass.Counter
        <input
            type="button"
            value="+1"
            @onclick="addOne"/>
    </div>
    <div>
        Message: @cascadingClass.Message
    </div>
</div>

@code {

    [CascadingParameter(Name = "CascadingClassParam")]
    protected CascadingClass cascadingClass { get; set; }

    private void addOne()
    {
        cascadingClass.AddOne();
    }

}
MiBol
  • 1,985
  • 10
  • 37
  • 64
  • 1
    I was going to post an answer, but can't. You add an event in the `CascadingClass` and raise it whenever you change anything in the class. Any component needing to update registers for the event in `OnInitialized` and calls `StateHasChanged`. – MrC aka Shaun Curtis Mar 22 '22 at 20:18
  • Yes, thanks for the update @MrCakaShaunCurtis - I added my solution into the Question body – MiBol Mar 22 '22 at 20:41

0 Answers0