简体   繁体   English

使用将接口而不是具体类传递给@ChildContent 的 [CascadingParameter]<cascadingvalue> 在 blazor</cascadingvalue>

[英]Passing interfaces instead of concrete classes into @ChildContent's [CascadingParameter] using <CascadingValue> in blazor

I have Item implementing IItem , and ItemContainer implementing IItemContainer .我有实现IItemContainerItem和实现IItemItemContainer

In ItemContainer.razor I have the following, passing itself to all its @ChildContent :ItemContainer.razor我有以下内容,将自己传递给它的所有@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:Item class 我有以下内容:

[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);我希望当第一个<Item>调用它的OnInitialized时, <ItemContainer>已经将自己传递给[CascadingParameter] public IItemContainer ItemContainer {get;set;} ,所以[CascadingParameter] public IItemContainer ItemContainer {get;set;}不会是 null 和ItemContainer.AddItem(this); will be successfully called and add the <Item> to the <ItemContainer> 's List<IItem> Items .将成功调用并将<Item>添加到<ItemContainer>List<IItem> Items

This is not an issue if I use concrete classes, ie ItemContainer instead of IItemContainer for <CascadingValue Value="this"> .如果我使用具体的类,这不是问题,即 ItemContainer 而不是 IItemContainer 的<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).但是,当<CascadingValue Value="this"> this this 是接口而不是具体的 class 时,不会自动进行强制转换,并且会抛出 null 异常(ItemContainer 未传递到级联参数中)。

And when I try to cast it using <CascadingValue TValue="IItemContainer" Value="(IItemContainer)this"> , exception will be thrown.当我尝试使用<CascadingValue TValue="IItemContainer" Value="(IItemContainer)this">进行投射时,将引发异常。

I want to pass interfaces instead of concrete classes into cascading params.我想将接口而不是具体类传递给级联参数。 Is there a way to make this work?有没有办法使这项工作?

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你还是要通过this

Here's the way to do that:这是这样做的方法:

ItemContainer.razor ItemContainer.razor

<CascadingValue Value="this">
    @ChildContent
</CascadingValue>

@code{
  List<IItem> Items;
  void AddItem(IItem item) => Items.Add(item);
  .
  .
  .
}

Item.razor项目.razor

@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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM