Reputation: 685
I have Item
implementing IItem
, and ItemContainer
implementing IItemContainer
.
In ItemContainer.razor
I have the following, passing itself to all its @ChildContent
:
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
@code{
List<IItem> Items;
void AddItem(IItem item) => Items.Add(item);
.
.
.
}
And in the Item
class I have the following:
[CascadingParameter] public IItemContainer ItemContainer {get;set;}
protected override void OnInitialized()
{
ItemContainer.AddItem(this);
}
RenderFragment RenderStuff => Do some rendering stuff with ItemContainer
.
.
.
Say that I have the following:
<ItemContainer>
<Item>
<Item>
<Item>
</ItemContainer>
I expect that by the time the first <Item>
calls its OnInitialized
,
the <ItemContainer>
would already have passed itself into [CascadingParameter] public IItemContainer ItemContainer {get;set;}
,
so [CascadingParameter] public IItemContainer ItemContainer {get;set;}
will not be null,
and ItemContainer.AddItem(this);
will be successfully called and add the <Item>
to the <ItemContainer>
's List<IItem> Items
.
This is not an issue if I use concrete classes, i.e. ItemContainer instead of IItemContainer for <CascadingValue Value="this">
.
However, when the this
of <CascadingValue Value="this">
is an interface and not an concrete class, casting does not automatically happen, and null exception will be thrown (ItemContainer not passed into the cascading param).
And when I try to cast it using <CascadingValue TValue="IItemContainer" Value="(IItemContainer)this">
, exception will be thrown.
I want to pass interfaces instead of concrete classes into cascading params. Is there a way to make this work?
Upvotes: 0
Views: 701
Reputation: 45704
And when I try to cast it using
<CascadingValue TValue="IItemContainer"
Value="(IItemContainer)this">
exception will be thrown.
You don't do that like this. You still have to pass this
Here's the way to do that:
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
@code{
List<IItem> Items;
void AddItem(IItem item) => Items.Add(item);
.
.
.
}
@implements IItem
[CascadingParameter] public IItemContainer ItemContainer {get;set;}
protected override void OnInitialized()
{
// Note: The first ItemContainer (left to right) is the class name,
// the second is the name of the cascading parameter property. If the compiler
// fail to recognize that (I guess she won't), change this property to
// ContainerItemSet, as for instance. Otherwise, it should work perfectly
// fine.
((ItemContainer)(object)(ItemContainer)).AddItem(this);
}
Upvotes: 1