BlazorWebFormsComponents
BlazorWebFormsComponents copied to clipboard
Default the Context for a control to "Item"
Need to do some research into how Blazor sets "@context" as the default context variable name for child components. To maintain Web Forms compatibility we should reset the default for THESE COMPONENTS ONLY to @Item
Are you wanting to not have to convert explicitly
<ListView
@ref="simpleListView"
runat="server"
Context="Item"
SelectMethod="simpleListView_GetData"
ItemType="SharedSampleObjects.Models.Widget">
<ItemTemplate>
<tr>
<td>@Item.Id </td>
<td>@Item.Name </td>
<td>@Item.Price.ToString("c") </td>
<td>@Item.LastUpdate.ToString("d") </td>
</tr>
</ItemTemplate>
where the Context="Item" changes @context to @item
What you want is for the BlazorWebFormsComponents.ListView to be able to recognize the @item notation without the need for the Context="Item" markup in the client code.
You'd then have
<ListView
@ref="simpleListView"
runat="server"
SelectMethod="simpleListView_GetData"
ItemType="SharedSampleObjects.Models.Widget">
<ItemTemplate>
<tr>
<td>@Item.Id </td>
<td>@Item.Name </td>
<td>@Item.Price.ToString("c") </td>
<td>@Item.LastUpdate.ToString("d") </td>
</tr>
</ItemTemplate>
Precisely! This helps the syntax adhere to the standard used in Web Forms and eliminates another piece of Blazor specific syntax that needs to be added when migrating from ASP.NET Web Forms.
Oooh! so we COULD override the Context parameter somewhere in the stack to force it.
Need to research a little further
The commit is actually against an internal ComponentTagHelper… but it gives a place to start.
L276
however it all looks very internal.
Without thinking about how this might actually be implemented, a possible dirty first step could be
- intercept the Blazor rendering
- replace
@itemwith@context - pass that back into the Blazor renderer
which sounds like a "simple" decorator.
BlazorWebFormComponents needs to be able to access the TagHelperDescriptorBuilder here, and apply the same behaviour as the CreateContextParameter with the childContentName = item
private void CreateContextParameter(TagHelperDescriptorBuilder builder, string childContentName)
{
builder.BindAttribute(b =>
{
b.Name = "Context";
b.TypeName = typeof(string).FullName;
b.Metadata.Add(BlazorMetadata.Component.ChildContentParameterNameKey, bool.TrueString);
if (childContentName == null)
{
b.Documentation = Resources.ChildContentParameterName_TopLevelDocumentation;
}
else
{
b.Documentation = string.Format(Resources.ChildContentParameterName_Documentation, childContentName);
}
});
}
The test for this in Blazor : ChildContentRazorIntegrationTest see :
- Render_MultipleChildContent_ContextParameterOnComponent
- Render_MultipleChildContent_ContextParameterOnComponent_SetsSameName

Notice how the Context="Item" attribute does not actually appear in the component's Frames.
so.. could we override this by adding a string Context {get;set;} to a base class and default it to Item? Hmm... feels like a good experiment.
Update: doesn't work. Tagging @rynowak and @danroth27 for insight
We deliberately do not allow a component to set the name of context. This creates a guessing game, where different components in the ecosystem have different behaviors, and users have to figure it out for each library they use.
We’d like to extend the defaults to allow the “Item” that was the default in web forms to be usable as a default as well.
Jeff
On Feb 8, 2020, at 14:35, Ryan Nowak [email protected] wrote:
We deliberately do not allow a component to set the name of context. This creates a guessing game, where different components in the ecosystem have different behaviors, and users have to figure it out for each library they use.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.
While it would be fun to research this further, and find some point of DI that could subvert the Blazor teams deliberate enforcement of the context syntax. I think there might be better places to invest in.
A ticket should be created to document this explicit requirement for conversion.
it might be nice if the Blazor team add some specific WebFormsSupport().
services.AddWebFormsSupport();
This might do things like …
- override the internal ?TagHelper? that manages / sets the
Context="Item"
#49 another unsupported (but we'll do it if the community shouts loud enough)
I think your work on DataBinding.Eval has resolved this. ??
Unfortunately I don't think it will. Eval returns a RenderFragment that gets rendered as a string.
We would need to implement an Item property that returns the type of @context.