Reputation: 695
I have created a TestComponent.razor
@typeparam TValue
@code {
private TValue Type { get; set; }
[Parameter] public string String { get; set; }
}
In the index.razor page I have the following:
@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";
}
I cannot pass Type myType
into TValue
, unless I make myType
a @typeparam
of the current page
Why is this happening and is there a way to pass variables into a component's @typeparam
?
Upvotes: 5
Views: 6138
Reputation: 388273
You cannot create Blazor components using a “variable” generic type argument. Just like with normal generic types in C#, these type arguments need to be known at compile time and as such you will have to specify your type directly when creating the component.
In your case, this could look like this:
<SampleComponent TValue="string" Type="some string" String="@myString" />
Since you have used your generic type argument TValue
for the property Type
, you can also leave out the TValue="string"
explicitly and have the compiler complete that for you:
<SampleComponent Type="some string" String="@myString" />
If you want to create a component dynamically then what you can do is to dynamically create a RenderFragment
that renders the component. That way
The only way to create a generic component with a dynamic type argument at run time would be to use reflection. You can create a RenderFragment
to create a component dynamically:
<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";
}
This would render the SampleComponent
with the generic type argument MyType
inside the div.
Upvotes: 10