如何在 Blazor Server 应用中将数据对象和 KeyEventArgs 从子组件传递到父组件

How to pass a data object and KeyEventArgs from a Child Component to a Parent Component in Blazor Server App

提问人:Faheem Ahmad 提问时间:2/11/2023 更新时间:2/12/2023 访问量:182

问:

在 Blazor Server 应用中,我有一个子组件,上面有一个按钮。子组件具有来自绑定到(Book objec)的父组件的一些数据。当我在子组件上单击此按钮时,我正在父组件中调用单击事件处理程序。但是,父项中的此按钮诊所事件处理程序需要知道用户是否在按下 Shift 键的情况下单击了 chid 上的按钮。我能够将数据对象(Book 对象)从 Child 传递给父级,但我无法弄清楚如何将 KeyEventArg 也从 Child 传递给父级,这将帮助父级知道当用户单击子项上的按钮时是否按下了 Shift 键。我将不胜感激。 我包括我的子组件和父组件的代码。

// Code for the Child

<div class="card-faheem">
        
        <div >
            <span class="span-fa">@BookContainer.ValueWord</span>
            
        </div>
        <div class="button-div">
            <button class="btn btn-primary" title="View" @onclick="@(async () => await OnSelected.InvokeAsync(BookContainer))">
            <i class="bi bi-binoculars"></i>
        </button>
        </div>
    </div>

@code 
{
    [Parameter, EditorRequired] public TextContainer BookContainer { get; set; } = default!;
    [Parameter, EditorRequired] public EventCallback<TextContainer> OnSelected { get; set; }
}

// Code for the parent
@inject TextContainerRepository tcr
<h3>CardParentPage</h3>

<div >
    @foreach (var book in books)
    {
        <CardComponent BookContainer=book OnSelected="HandleSelectedBook" />
    }
    </div>
@code {

    List<TextContainer> books { get; set; }

    protected override async Task OnInitializedAsync()
    {
        books = tcr.GetBooksByAuthorName("Jane Auston");

    }


    private void HandleSelectedBook(TextContainer book)
    {
       if (true)
       //     (args.ShiftKey)
        {
            // Do something if ShifKey was pressed
        } else
        {
            // Do something else if ShifKey was no pressed
        }

    }


}

enter image description here

enter image description here

C# Blazor 参数传递 KeyEventArgs

评论


答:

2赞 MrC aka Shaun Curtis 2/12/2023 #1

您可以创建一个简单的 或 ,但在一次性情况下最简单的是 .structrecordTuple

[Parameter, EditorRequired] public EventCallback<Tuple<MouseEventArgs,TextContainer>> OnSelected { get; set; }
 <button class="btn btn-primary" title="View" @onclick="(e) => Selected(e, BookContainer)">

//....

    private async Task Selected(MouseEventArgs e, TextContainer book)
        => await OnSelected.InvokeAsync(new Tuple<MouseEventArgs, TextContainer>(e, book));


    private void HandleSelectedBook(Tuple<MouseEventArgs,TextContainer> data)
    {
        var x = data.Item1.AltKey;

        //.....
    }

这是我的演示代码:

元件:

<h3>BookComponent</h3>
<button class="btn btn-success" @onclick="@((e) => OnSelected(e, "Mansfield Park"))">Select Pride and Passion</button>
@code {
    [Parameter] public EventCallback<Tuple<MouseEventArgs, string>> BookSelected { get; set; }

    private async Task OnSelected(MouseEventArgs e, string book)
        => await BookSelected.InvokeAsync(new Tuple<MouseEventArgs, string>(e, book));
}

页:

@page "/"
<PageTitle>Index</PageTitle>

<BookComponent BookSelected=OnBookSelected />

<div class="alert alert-info">
    @message
</div>

@code {
    private string message = "Not Set";

    private Task OnBookSelected(Tuple<MouseEventArgs,string> data)
    {
        message = data.Item1.ShiftKey ? $"Shifted {data.Item2}" : $"{data.Item2}";
        return Task.CompletedTask;
    }
}

评论

0赞 Faheem Ahmad 2/12/2023
非常感谢您为我的问题提供解决方案。我已经尝试过这个,但是在我的父类中,当我尝试使用此事件回调时,我收到错误消息 CS1503:参数 2:“可以从'方法组'转换为'EventCallback',如图所示。我希望得到进一步的指导。
0赞 MrC aka Shaun Curtis 2/12/2023
抱歉,但 C# 编译器无法正确识别元组声明,所以我在那里给了你一个错误的转向。请参阅我使用不带命名参数的传统完整元组声明的修订答案。