0

The function is inside a page and I want to run it from a component higher up in the tree.

Interface

enter image description here

Actual structure

enter image description here

José Guilherme
  • 57
  • 1
  • 10
  • In general you abstract what the method does into a service, inject the service and call it from wherever you want. If the method involves mutating the data the page is using to drive it's UI, you trigger an event in the service. Components that depend on that data register for the event and update their UI when the event is invoked. See this and many other answers on the notification pattern - https://stackoverflow.com/a/75944088/13065781 – MrC aka Shaun Curtis Jul 13 '23 at 17:08
  • https://stackoverflow.com/a/76449070/13065781 - https://stackoverflow.com/a/69562295/13065781 – MrC aka Shaun Curtis Jul 13 '23 at 17:09
  • Does this answer your question? [Call method in MainLayout from a page component in Blazor](https://stackoverflow.com/questions/58123063/call-method-in-mainlayout-from-a-page-component-in-blazor) – RBee Jul 15 '23 at 09:09

1 Answers1

0

I did something similar when creating an on screen keyboard component that was rendered inside a parent component. Here's part of the code:

//The variable used for binding is not the same as the paremeter defined below.

<InputText class="form-control" @bind-InputString="inputString" @bind-Value="inputString"/>
<br/>
<div style="text-align:center; display:block; margin-left:12em; margin-right:auto">
    <div id="virtualKeyboard">
        @*Fila 1*@
        <div class="row">
            <button type="button" id="btn7" @onclick="@(() => InputKey("7"))" class="btn btn-primary col-lg-3" style="margin-right:5px">7</button>
            <button type="button" id="btn8" @onclick="@(() => InputKey("8"))" class="btn btn-primary col-lg-3" style="margin-right:5px; margin-left:5px">8</button>
            <button type="button" id="btn9" @onclick="@(() => InputKey("9"))" class="btn btn-primary col-lg-3" style="margin-left:5px">9</button>
        </div>
        <br />
        ... You get the idea of what goes here
        </div>
    </div>
</div>

@code {
    //Here we match the variable used for binding with the parameters defined below.
    private string inputString
    {
        get => InputString;
        set
        {
            InputString = value;
            InputStringChanged.InvokeAsync(value);
        }
    }

    //Important: whatever name you set here must match the eventcallback name before the "Changed" suffix
    [Parameter]
    public string InputString { get; set; }
    
    //The EventCallback parameter must always end with "Changed"
    [Parameter]
    public EventCallback<string> InputStringChanged { get; set; }



    private void InputKey(string number)
    {
        inputString += number;
    }

    private void InputDelete()
    {
        if (inputString.Length > 0)
        {
            inputString = inputString.Remove(inputString.Length - 1, 1);
        }
    }

    private void InputClear()
    {
        inputString = string.Empty;
    }


    protected override void OnInitialized()
    {
        inputString = "";
    }
}

Later on the parent component you render the child component. For example:

<EditForm Model="@yourModel" >
            <label for="personalId">PersonalId:</label>
            <Numpad @bind-InputString="yourModel.PersonalId" />
</EditForm>

On my example a keypad is displayed, the InputKey() function is called from within the Numpad component whenever a key button is clicked, but it is rendered inside a parent component higher in the tree and the values are bound correctly to the model.

I hope this helps solving your question or gives you some idea on how to proceed.