У меня есть компонент мастера Blazor, который содержит форму. Элемент управления мастера состоит из 2 компонентов Blazor -
Wizard.razor
<CascadingValue Value="this">
<div id="@Id">
<div id="container-fluid">
@ChildContent
</div>
</div>
<button class="btn btn-primary btn-lg" type="button"
disabled="@(ActiveStepIx == 0)" @onclick="GoBack">
Previous
</button>
<button class="btn btn-primary btn-lg"
type="@(IsLastStep ? "submit" : "button")" @onclick="GoNext">
@(IsLastStep ? "Submit" : "Next")
</button>
</CascadingValue>
/// <summary>
/// Wizard Component
/// </summary>
public partial class Wizard
{
/// <summary>
/// List of <see cref="WizardStep"/> added to the Wizard
/// </summary>
protected internal List<WizardStep> Steps = new List<WizardStep>();
/// <summary>
/// The control Id
/// </summary>
[Parameter]
public string Id { get; set; }
/// <summary>
/// The ChildContent container for <see cref="WizardStep"/>
/// </summary>
[Parameter]
public RenderFragment ChildContent { get; set; }
/// <summary>
/// The Active <see cref="WizardStep"/>
/// </summary>
[Parameter]
public WizardStep ActiveStep { get; set; }
/// <summary>
/// The Index number of the <see cref="ActiveStep"/>
/// </summary>
[Parameter]
public int ActiveStepIx { get; set; }
/// <summary>
/// Determines whether the Wizard is in the last step
/// </summary>
public bool IsLastStep { get; set; }
/// <summary>
/// Sets the <see cref="ActiveStep"/> to the previous Index
/// </summary>
protected internal void GoBack()
{
if (ActiveStepIx > 0)
SetActive(Steps[ActiveStepIx - 1]);
}
/// <summary>
/// Sets the <see cref="ActiveStep"/> to the next Index
/// </summary>
protected internal void GoNext()
{
if (ActiveStepIx < Steps.Count - 1)
{
SetActive(Steps[(Steps.IndexOf(ActiveStep) + 1)]);
}
else
{
// TODO: SUBMIT THE FORM
Console.WriteLine("FORM SUBMITTED");
}
}
/// <summary>
/// Populates the <see cref="ActiveStep"/> the Sets the passed in <see cref="WizardStep"/> instance as the
/// </summary>
/// <param name="step">The WizardStep</param>
protected internal void SetActive(WizardStep step)
{
ActiveStep = step ?? throw new ArgumentNullException(nameof(step));
ActiveStepIx = StepsIndex(step);
if (ActiveStepIx == Steps.Count - 1)
IsLastStep = true;
else
IsLastStep = false;
}
/// <summary>
/// Retrieves the index of the current <see cref="WizardStep"/> in the Step List
/// </summary>
/// <param name="step">The WizardStep</param>
/// <returns></returns>
public int StepsIndex(WizardStep step) => StepsIndexInternal(step);
protected int StepsIndexInternal(WizardStep step)
{
if (step == null)
throw new ArgumentNullException(nameof(step));
return Steps.IndexOf(step);
}
/// <summary>
/// Adds a <see cref="WizardStep"/> to the WizardSteps list
/// </summary>
/// <param name="step"></param>
protected internal void AddStep(WizardStep step)
{
Steps.Add(step);
}
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
SetActive(Steps[0]);
StateHasChanged();
}
}
}
WizardStep.razor
@if (Parent.ActiveStep == this)
{
<div id="step-@(Parent.StepsIndex(this) + 1)">
@ChildContent
</div>
}
/// <summary>
/// Wizard Step component
/// </summary>
public partial class WizardStep
{
/// <summary>
/// The <see cref="Wizard"/> container
/// </summary>
[CascadingParameter]
protected internal Wizard Parent { get; set; }
/// <summary>
/// The Child Content of the current <see cref="WizardStep"/>
/// </summary>
[Parameter]
public RenderFragment ChildContent { get; set; }
/// <summary>
/// The Name of the step
/// </summary>
[Parameter]
public string Name { get; set; }
protected override void OnInitialized()
{
Parent.AddStep(this);
}
}
Мастер содержит форму. Я отображаю эту форму в модальном всплывающем окне, и на родительской странице у меня есть метод с именем HandleValidSubmit (), который отправляет форму. Как я могу вызвать этот метод с помощью кнопки «Отправить» на Wizard.razor?
ParentPage.razor
<EditForm Model="@ItemForTradeObject">
<Wizard Id="AddItemWizard">
<WizardStep Name="Item">
<div class="form-group col-md-6">
<label class="sr-only" for="itemName">Item Name</label>
<div class="input-group">
<InputText id="itemName" class="form-control" @bind-Value="@ItemForTradeObject.ItemName" /> <ValidationMessage For="@(() => ItemForTradeObject.ItemName)" />
</div>
</WizardStep>
<WizardStep Name="Costing">
<div class="form-group col-md-6">
<label class="sr-only" for="shippingCost">Cost Price</label>
<div class="input-group">
<div class="input-group-addon">£</div>
<InputText id="costPrice" class="form-control" @bind-Value="@ItemForTradeObject.CostPrice" />
</div>
<ValidationMessage For="@(() => ItemForTradeObject.CostPrice)" />
</div>
</WizardStep>
</Wizard>
@code {
private async void HandleValidSubmit()
{
if (ItemForTradeObject.Id == 0)
{
// Add
ItemForTradeObject.UserId = await localStorage.GetItemAsync<string>("userid");
await Http.PostJsonAsync("api/trading/add", ItemForTradeObject);
}
else
{
// Update
ItemForTradeObject.UserId = await localStorage.GetItemAsync<string>("userid");
await Http.PostJsonAsync("api/trading/update", ItemForTradeObject);
}
await CloseTaskModal();
DataChanged?.Invoke();
}
}