C# Blazor:如何在通用组件中将事件传递给onClick函数

C# Blazor:如何在通用组件中将事件传递给onClick函数,c#,blazor,C#,Blazor,我正在为我正在制作的网站制作一个表格组件。我希望能够在一个页面上创建、更新、添加和删除表中的条目。我也将在整个网站上使用这个组件,并将许多种类的类作为输入。我去学校是为了学习如何做到这一点。我还认为在表中的每一行都有一个内部组件是明智的。以下是我目前的代码: 可编辑类.剃须刀 @using WbotV2.Data @using System @using System.Collections @using System.Reflection @typeparam TItem <t

我正在为我正在制作的网站制作一个表格组件。我希望能够在一个页面上创建、更新、添加和删除表中的条目。我也将在整个网站上使用这个组件,并将许多种类的类作为输入。我去学校是为了学习如何做到这一点。我还认为在表中的每一行都有一个内部组件是明智的。以下是我目前的代码:

可编辑类.剃须刀

@using WbotV2.Data
@using System
@using System.Collections
@using System.Reflection
@typeparam TItem

    <tr>
        @foreach (var datum in Data)
        {
            <td>@datum</td>
        }
        <td><button class="btn btn-success">Edit</button></td>
        <td>@ChildContent</td>
    </tr>


@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter] 
    public TItem Item { get; set; }

    public List<string> Data;
    public bool Editable = false;
    protected override async Task OnInitializedAsync()
    {
        Data = GetData(Item);
    }

    public static List<string> GetData<T>(T instance)
    {
        List<string> ret = new List<string>();
        FieldInfo[] infos = typeof(T).GetFields();
        foreach (FieldInfo info in infos)
        {
            ret.Add(info.GetValue(instance).ToString());
        }
        return ret;
    }
}
@using WbotV2.Data
@using System
@using System.Collections
@using System.Reflection
@typeparam TItem

<table class="table">
    <thead>
        <tr>
            @foreach (string header in Headers)
            {
                <th>@header</th>   
            }
            <td>Edit</td>
            <td>Delete</td>
            <td><button class="btn btn-primary">Add</button></td>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Items)
        {
            <EditableClass Item="@item"><button class="btn btn-danger"  @onclick="(Delete(item))">Delete</button></EditableClass>
        }
    </tbody>
</table>


@code {
        [Parameter] 
        public IList<TItem> Items { get; set; }

        [Parameter] 
        public TableUtilityClass<TItem> DataInstance { get; set; }

    public string[] Headers;

    protected override async Task OnInitializedAsync()
    {
        Headers = GetHeaders();
    }

    public string[] GetHeaders()
    {
        List<string> ret = new List<string>();
        FieldInfo[] infos = typeof(TItem).GetFields();
        foreach (FieldInfo info in infos)
        {
            ret.Add(info.Name);
        }
        return ret.ToArray();
    }

    public void Delete(TItem itemToDelete)
    {
        DataInstance.Delete(itemToDelete);
        StateHasChanged();
        Console.WriteLine("Here");
    }

    public void Add(TItem itemToAdd)
    {
        DataInstance.Add(itemToAdd);
        StateHasChanged();
        Console.WriteLine("Here");
    }

    public List<List<string>> GetDataString<T>(IEnumerable<T> instance)
    {
        List<List<string>> ret = new List<List<string>>();
        foreach (T item in instance)
        {
            ret.Add(new List<string>());
            FieldInfo[] infos = typeof(T).GetFields();
            foreach (FieldInfo info in infos)
            {
                ret[ret.Count - 1].Add(info.GetValue(item).ToString());
                Console.WriteLine($"{info.Name}: {info.GetValue(item)}");
            }
        }
        return ret;
    }
}
@使用WbotV2.Data
@使用系统
@使用System.Collections
@使用系统反射
@typeparam滴度
@foreach(数据中的var数据)
{
@基准面
}
编辑
@儿童内容
@代码{
[参数]
公共RenderFragment ChildContent{get;set;}
[参数]
公共滴度项{get;set;}
公开名单数据;
公共bool可编辑=false;
受保护的重写异步任务OnInitializedAsync()
{
数据=获取数据(项目);
}
公共静态列表GetData(T实例)
{
List ret=新列表();
FieldInfo[]infos=typeof(T).GetFields();
foreach(信息中的FieldInfo)
{
ret.Add(info.GetValue(instance.ToString());
}
返回ret;
}
}
这个组件应该允许我将一个类作为参数传入,然后编辑它的字段。它也不应该把用户带到一个单独的页面来编辑它(如果可能的话,我希望将它内联到表中)。我的想法是使用绑定来实现这一点,但是类名是任意的,所以我不知道如何将其传递给@bind,这正是我遇到的问题

表格组件.剃须刀

@using WbotV2.Data
@using System
@using System.Collections
@using System.Reflection
@typeparam TItem

    <tr>
        @foreach (var datum in Data)
        {
            <td>@datum</td>
        }
        <td><button class="btn btn-success">Edit</button></td>
        <td>@ChildContent</td>
    </tr>


@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter] 
    public TItem Item { get; set; }

    public List<string> Data;
    public bool Editable = false;
    protected override async Task OnInitializedAsync()
    {
        Data = GetData(Item);
    }

    public static List<string> GetData<T>(T instance)
    {
        List<string> ret = new List<string>();
        FieldInfo[] infos = typeof(T).GetFields();
        foreach (FieldInfo info in infos)
        {
            ret.Add(info.GetValue(instance).ToString());
        }
        return ret;
    }
}
@using WbotV2.Data
@using System
@using System.Collections
@using System.Reflection
@typeparam TItem

<table class="table">
    <thead>
        <tr>
            @foreach (string header in Headers)
            {
                <th>@header</th>   
            }
            <td>Edit</td>
            <td>Delete</td>
            <td><button class="btn btn-primary">Add</button></td>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Items)
        {
            <EditableClass Item="@item"><button class="btn btn-danger"  @onclick="(Delete(item))">Delete</button></EditableClass>
        }
    </tbody>
</table>


@code {
        [Parameter] 
        public IList<TItem> Items { get; set; }

        [Parameter] 
        public TableUtilityClass<TItem> DataInstance { get; set; }

    public string[] Headers;

    protected override async Task OnInitializedAsync()
    {
        Headers = GetHeaders();
    }

    public string[] GetHeaders()
    {
        List<string> ret = new List<string>();
        FieldInfo[] infos = typeof(TItem).GetFields();
        foreach (FieldInfo info in infos)
        {
            ret.Add(info.Name);
        }
        return ret.ToArray();
    }

    public void Delete(TItem itemToDelete)
    {
        DataInstance.Delete(itemToDelete);
        StateHasChanged();
        Console.WriteLine("Here");
    }

    public void Add(TItem itemToAdd)
    {
        DataInstance.Add(itemToAdd);
        StateHasChanged();
        Console.WriteLine("Here");
    }

    public List<List<string>> GetDataString<T>(IEnumerable<T> instance)
    {
        List<List<string>> ret = new List<List<string>>();
        foreach (T item in instance)
        {
            ret.Add(new List<string>());
            FieldInfo[] infos = typeof(T).GetFields();
            foreach (FieldInfo info in infos)
            {
                ret[ret.Count - 1].Add(info.GetValue(item).ToString());
                Console.WriteLine($"{info.Name}: {info.GetValue(item)}");
            }
        }
        return ret;
    }
}
@使用WbotV2.Data
@使用系统
@使用System.Collections
@使用系统反射
@typeparam滴度
@foreach(标头中的字符串标头)
{
@标题
}
编辑
删除
添加
@foreach(项目中的var项目)
{
删除
}
@代码{
[参数]
公共IList项{get;set;}
[参数]
公共TableUtilityClass数据实例{get;set;}
公共字符串[]头;
受保护的重写异步任务OnInitializedAsync()
{
Headers=GetHeaders();
}
公共字符串[]GetHeaders()
{
List ret=新列表();
FieldInfo[]infos=typeof(TItem).GetFields();
foreach(信息中的FieldInfo)
{
ret.Add(信息名称);
}
返回返回返回到阵列();
}
公共作废删除(TItem itemToDelete)
{
Delete(itemToDelete);
StateHasChanged();
Console.WriteLine(“此处”);
}
公共无效添加(TItem itemToAdd)
{
添加(itemToAdd);
StateHasChanged();
Console.WriteLine(“此处”);
}
公共列表GetDataString(IEnumerable实例)
{
List ret=新列表();
foreach(实例中的T项)
{
ret.Add(新列表());
FieldInfo[]infos=typeof(T).GetFields();
foreach(信息中的FieldInfo)
{
ret[ret.Count-1].Add(info.GetValue(item.ToString());
Console.WriteLine($“{info.Name}:{info.GetValue(item)}”);
}
}
返回ret;
}
}
这个组件应该在一个表中包含许多可编辑类组件,并处理添加和删除新条目的操作。我当前的问题是删除,我已经尝试过实现,但在这一行上出现了无法从void转换为Microsoft.AspNetCore.Components.EventCallback错误
Delete
我也尝试过并。我也希望在这里得到一些帮助,要么解决这个错误,要么找到一个聪明的解决方法

表格实用程序类.cs

using System.Threading.Tasks;

namespace WbotV2.Data
{
    public abstract class TableUtilityClass<T>
    {
        public abstract Task Delete(T Item);
        public abstract Task Add(T Item);
    }
}
使用System.Threading.Tasks;
命名空间WbotV2.Data
{
公共抽象类TableUtilityClass
{
公共摘要任务删除(T项);
公共摘要任务添加(T项);
}
}
这个类应该能够帮助您轻松地与许多不同类型的服务交互,正如我预期的那样

最后,这里是my Countries.razor(表格组件进入的页面)

@page”/countries
@使用WbotV2.Data
@注入WbotCountryService CountryService
国家信息
@如果(国家==null)
{
加载

} 其他的 { } @代码{ 公开名单国家; 受保护的重写异步任务OnInitializedAsync() { countries=等待CountryService.GetCountriesAsync(); } }
对于那些想知道国家/地区服务是这样的人:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WbotV2.Data
{
    public class WbotCountryService : TableUtilityClass<WbotCountry>
    {
        public WbotData WbotDataInstance;

        public WbotCountryService()
        {
            WbotDataInstance = WbotData.LoadData();
        }
        public Task<List<WbotCountry>> GetCountriesAsync()
        {
            return Task.FromResult(WbotDataInstance.countries);
        }

        public override Task Delete(WbotCountry c)
        {
            WbotDataInstance.countries.Add(c);
            WbotDataInstance.SaveData();

            return Task.CompletedTask;
        }
        public override Task Add(WbotCountry c)
        {
            WbotDataInstance.countries.Remove(c);
            WbotDataInstance.SaveData();

            return Task.CompletedTask;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
命名空间WbotV2.Data
{
公共类WbotCountryService:TableUtilityClass
{
公共WbotData WbotDataInstance;
公共WbotCountryService()
{
WbotDataInstance=WbotData.LoadData();
}
公共任务GetCountriesAsync()
{
返回Task.FromResult(WbotDataInstance.countries);
}
公共覆盖任务删除(WBOTC国家/地区)
{
WbotDataInstance.countries.Add(c);
WbotDataInstance.SaveData();
返回Task.CompletedTask;
}
公共覆盖任务添加(WBOTC国家/地区)
{
WbotDataInstance.countries.Remove(c);
WbotDataInstance.SaveData();
返回Task.CompletedTask;
}
}
}
任何帮助都将被感激

这是有效的:

可编辑类
@使用WbotV2.Data
@使用系统
@使用System.Collections
@使用系统反射
@typeparam滴度
@foreach(数据中的var数据)
{
@基准面
}
编辑
@儿童内容
@代码{
[参数]
公共渲染碎片
<EditableClass Item="@item"><button class="btn btn-danger" @onclick="@(() => Delete(item))">DeleteMe</button></EditableClass>


public void Delete(TItem itemToDelete)
    {
        DataInstance.Delete(itemToDelete);
      //  StateHasChanged();
       // Console.WriteLine("Here");
    }