I have a templated component (a tooltip) that has a parameter and passes that parameter in context to child content. That parameter is a wrapper for ElementReference
. The purpose of this is to get back to the tooltip the child's reference, once it is set.
What I want to do is to store a particular instance of that tooltip component in a reusable RenderFragment
in several places.
But I get the error The name 'context' does not exists in the current context
.
This is original question, but it proved to be oversimplified. Please go to second separation line, with sample more resembling my situation.
Here is a sample (not that tooltip, but simplified code that has exactly the same problem).
Templated component RenderFragTempl
:
@inherits ComponentBase
<span id="@(Ref)">
@IntChildContent(Ref)
</span>
@code {
[Parameter] public RenderFragment<int> IntChildContent { get; set; }
[Parameter] public int Ref { get; set; }
}
and the call in Index.razor
:
@page "/"
@using BlazorServer.Pages.StackOverflow
<RenderFragTempl Ref="10">
<IntChildContent>
<p>@context</p>
</IntChildContent>
</RenderFragTempl>
<br />
@test
@code {
//compiler error CS0103: The name 'context' does not exist in the current context
private readonly RenderFragment test = @<RenderFragTempl Ref="10001">
<IntChildContent>
<p>@context</p>
</IntChildContent>
</RenderFragTempl>;
}
EDIT: 1
I have a tooltip component that has a child content. Tooltip will be shown whenever the mouse hovers over that child content. But tooltip does not wrap the child content with anything. So if you check out the source, you will only see the child content without any indication of the tooltip. The moment mouse cursor hovers over the child content, the tooltip container is added to the bottom of the page and is position right over that child content. This is quite problematic to achieve in blazor because the tooltip needs to have the reference to the child content. But references are established after parameters are filled. So a special wrapper is used to achieve that and Tooltip is built as a templated component.
So the wrapper for ElementReference
I use (curtesy of MatBlazor):
public class TargetForwardRef
{
private ElementReference _current;
public ElementReference Current
{
get => _current;
set
{
Set(value);
//this is just for debugging purpose
Console.WriteLine($"Ref: {value.Id ?? "null"}");
}
}
public void Set(ElementReference value) => _current = value;
}
My simplified Tooltip
as RenderFragTempl
(just the important bits)
@inherits ComponentBase
<span>
@UnboundChildContent(RefBack)
</span>
@code {
[Parameter] public RenderFragment<TargetForwardRef> UnboundChildContent { get; set; }
[Parameter] public TargetForwardRef RefBack { get; set; } = new TargetForwardRef();
}
And my index.razor
@page "/"
@*
//this is working, will printout to console `<span>` reference id, you will be
//able to find it once you go to source; I added this here for reference
*@
<RenderFragTempl>
<UnboundChildContent>
<span @ref="@context.Current">Span content</span>
</UnboundChildContent>
</RenderFragTempl>
<br/>
@test
@code {
//compiler error CS0103: The name 'context' does not exist in the current context
private readonly RenderFragment test =
@<RenderFragTempl>
<UnboundChildContent>
<span @ref="@context.Current">Hover to show tooltip</span >
</UnboundChildContent>
</RenderFragTempl>;
}
To answer the question - why I am trying to use RenderFragment
- imagine I have a collection of cards - let's say 150. The card component accepts as a parameter IList<RenderFragment>
for rendering buttons on a card. I want to pass my icon with tooltip to that card. I need to have access to Tooltip's context.
I tried renaming context to something else, but I get the same error (except in the error there is new context name).