如何在Blazor组件的@typeparam中传递变量

4

我已经创建了一个名为 TestComponent.razor 的组件。

@typeparam TValue

@code {
    private TValue Type { get; set; }
    [Parameter] public string String { get; set; }
}


在index.razor页面中,我有以下内容:
@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

<ComponentFactory.Data.SampleComponent TValue="@myType" String="@myString"></ComponentFactory.Data.SampleComponent>

@code{
    Type myType { get; set; } = typeof(string);
    string myString { get; set; } = "hello";
}

如果我不将myType变成当前页面的@typeparam,就无法将Type myType传递给TValue

为什么会发生这种情况,是否有一种方法可以将变量传递到组件的@typeparam中?


最好描述一下你想要实现什么,因为当然可以通过创建接受类型的参数来将类型传递给组件,但我们不知道你想要做什么,因为你已经决定如何做“它”,发现该方法不起作用,然后只是问如何使该方法起作用,但实际上它是行不通的。解释一下你希望你的组件能够做什么,有人会能够提供帮助。 - Mister Magoo
1个回答

8

您不能使用“变量”泛型类型参数创建 Blazor 组件。与 C# 中的普通泛型类型一样,这些类型参数需要在编译时已知,因此在创建组件时必须直接指定类型。

在您的情况下,可能会像这样:

<SampleComponent TValue="string" Type="some string" String="@myString" />

由于您已经在属性 Type 中使用了通用类型参数 TValue,因此您可以省略显式的 TValue="string",让编译器自动完成:

<SampleComponent Type="some string" String="@myString" />

如果您想动态创建一个组件,那么您可以动态地创建一个RenderFragment来呈现该组件。这样做的好处是:
要在运行时创建具有动态类型参数的通用组件,则唯一的方法是使用反射。您可以创建一个RenderFragment来动态创建组件:
<div>
   @SampleComponentInstance
</div>

@code{
    RenderFragment SampleComponentInstance => builder =>
    {
        var type = typeof(SampleComponent<>).MakeGenericType(new[] { MyType });
        builder.OpenComponent(1, type);
        builder.AddAttribute(2, "String", MyString);
        builder.CloseComponent();
    };

    Type MyType { get; set; } = typeof(string);
    string MyString { get; set; } = "hello";
}

这将在 div 中呈现具有泛型类型参数 MyTypeSampleComponent

嗨,使用反射来创建具有动态类型的通用组件正是我想要实现的。我尝试过将TValue="@typeof(TItem).GetProperty(PropertyName).PropertyType"作为输入,但它会抛出错误。 - Josh
@Wlbjtsthy 我已经扩展了我的答案,并提供了一个动态创建组件的示例。 - poke
谢谢!它有效。但是只有在只有一个@typeparam时才有效。var type = typeof(SampleComponent<>).MakeGenericType(new[] { MyType, MySecondType });返回错误,说SampleComponent<>需要两个参数。是否有办法使其适用于多个参数? - Josh
原来我需要这样做:typeof(SampleComponent<,>).MakeGenericType(MyType, MySecondType); - Josh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接