英文:
ASP.NET Core Blazor: Cascading Parameters
问题
    [CascadingParameter]
    public DataGridComponent<TItem>? ContainerDataGridComponent { get; set; }
英文:
Here is the scenario I want to retrieve the child component parameters for the use of the parrant component.
Code for parent component:
    [Parameter]
    public List<TItem>? DataItems { get; set; }
    public List<ColumnDefinition>? Columns { get; set; }
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
    public void AddColumn(ColumnDefinition columnDefinition)
    {
        if (Columns is null)
            Columns = new();
        Columns.Add(columnDefinition);
        StateHasChanged();
    }
Code for child component:
    [CascadingParameter]
    public DataGridComponent<TItem>? ContainerDataGridComponent { get; set; }
    [Parameter]
    public required ColumnDefinition ColumnDefinition { get; set; } 
    protected override void OnInitialized()
    {
        base.OnInitialized();
        ContainerDataGridComponent?.AddColumn(ColumnDefinition);
    }
launch code:
<DataGridComponent DataItems="PersonDtos" TItem="PersonDto">
    <ColumnComponent TItem="PersonDto" ColumnDefinition="@(new(){DataField = " FirstName", Caption="First Name" })" ></ColumnComponent>
    <ColumnComponent TItem="PersonDto" ColumnDefinition="@(new(){DataField = "LastName", Caption = "Last Name"})" ></ColumnComponent>
    <ColumnComponent TItem="PersonDto" ColumnDefinition="@(new(){DataField = "CreatedDate", Caption = "Created Date"})" ></ColumnComponent>
    <ColumnComponent TItem="PersonDto" ColumnDefinition="@(new(){DataField = "UpdatedDate", Caption = "Updated Date"})" ></ColumnComponent>
</DataGridComponent>
My problem:
this property is always null
[CascadingParameter]
    public DataGridComponent<TItem>? ContainerDataGridComponent { get; set; }
......
What do I have to do?
答案1
得分: 4
不确定你在做什么,因为根据你提供的代码,这是你应该有的东西。你在 Grid 中进行级联吗?
public class ColumnDefinition
{
    public string? Name { get; set; }
}
GridItem
@typeparam TItem
<div class="alert alert-primary">
@ChildContent
</div>
@code {
    [CascadingParameter] public Grid<TItem>? ContainerDataGridComponent { get; set; }
    [Parameter, EditorRequired] public required ColumnDefinition ColumnDefinition { get; set; }
    [Parameter] public RenderFragment? ChildContent { get; set; }
    protected override void OnInitialized()
    {
        ContainerDataGridComponent?.AddColumn(this.ColumnDefinition);
    }
}
Grid
@typeparam TItem
<h3>Grid</h3>
<CascadingValue Value="this">
        @ChildContent
        <div class="alert alert-info">
            Registered columns: @Columns.Count()
        </div>
</CascadingValue>
@code {
    [Parameter] public List<TItem>? DataItems { get; set; }
    public List<ColumnDefinition>? Columns { get; set; }
    [Parameter] public RenderFragment? ChildContent { get; set; }
    public void AddColumn(ColumnDefinition columnDefinition)
    {
        if (Columns is null)
            Columns = new();
        Columns.Add(columnDefinition);
        StateHasChanged();
    }
}
页面:
@page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
<Grid TItem="int">
    <GridItem TItem="int" ColumnDefinition="@(new ColumnDefinition { Name="Fred"})">Hello 1</GridItem>
    <GridItem TItem="int" ColumnDefinition="@(new ColumnDefinition { Name="Fred"})">Hello 2</GridItem>
    <GridItem TItem="int" ColumnDefinition="@(new ColumnDefinition { Name="Fred"})">Hello 3</GridItem>
</Grid>
评论:在这种情况下,你不需要级联整个组件,只需要注册方法,像这样的 Action:
GridItem
@typeparam TItem
<div class="alert alert-primary">
@ChildContent
</div>
@code {
    [CascadingParameter] private Action<ColumnDefinition>? Register { get; set; }
    [Parameter, EditorRequired] public required ColumnDefinition ColumnDefinition { get; set; }
    [Parameter] public RenderFragment? ChildContent { get; set; }
    protected override void OnInitialized()
    {
        this.Register?.Invoke(this.ColumnDefinition);
    }
}
Grid
@typeparam TItem
<h3>Grid</h3>
<CascadingValue Value="this.RegisterColumn">
        @ChildContent
        <div class="alert alert-info">
            Registered columns: @Columns.Count()
        </div>
</CascadingValue>
@code {
    [Parameter] public List<TItem>? DataItems { get; set; }
    [Parameter] public RenderFragment? ChildContent { get; set; }
    private readonly List<ColumnDefinition> Columns = new();
    private void RegisterColumn(ColumnDefinition columnDefinition)
    {
        if (!this.Columns.Any(item => item == columnDefinition ))
            Columns.Add(columnDefinition);
        StateHasChanged();
    }
}
<details>
<summary>英文:</summary>
I'm not sure what you're doing because this is what you should have based on the code you've supplied.  Are you doing the cascade in Grid?
```csharp
public class ColumnDefinition
{
    public string? Name { get; set; }
}
GridItem
@typeparam TItem
<div class="alert alert-primary">
@ChildContent
</div>
@code {
    [CascadingParameter] public Grid<TItem>? ContainerDataGridComponent { get; set; }
    [Parameter, EditorRequired] public required ColumnDefinition ColumnDefinition { get; set; }
    [Parameter] public RenderFragment? ChildContent { get; set; }
    protected override void OnInitialized()
    {
        ContainerDataGridComponent?.AddColumn(this.ColumnDefinition);
    }
}
Grid
@typeparam TItem
<h3>Grid</h3>
<CascadingValue Value="this">
        @ChildContent
        <div class="alert alert-info">
            Registered columns : @Columns.Count()
        </div>
</CascadingValue>
@code {
    [Parameter] public List<TItem>? DataItems { get; set; }
    public List<ColumnDefinition>? Columns { get; set; }
    [Parameter] public RenderFragment? ChildContent { get; set; }
    public void AddColumn(ColumnDefinition columnDefinition)
    {
        if (Columns is null)
            Columns = new();
        Columns.Add(columnDefinition);
        StateHasChanged();
    }
}
And the page:
@page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
<Grid TItem="int">
    <GridItem TItem="int" ColumnDefinition="@(new ColumnDefinition { Name="Fred"})">Hello 1</GridItem>
    <GridItem TItem="int" ColumnDefinition="@(new ColumnDefinition { Name="Fred"})">Hello 2</GridItem>
    <GridItem TItem="int" ColumnDefinition="@(new ColumnDefinition { Name="Fred"})">Hello 3</GridItem>
</Grid>
Comment: In this instance you don't need to cascade the whole component, just the registration method, as an Action like this:
GridItem
@typeparam TItem
<div class="alert alert-primary">
@ChildContent
</div>
@code {
    [CascadingParameter] private Action<ColumnDefinition>? Register { get; set; }
    [Parameter, EditorRequired] public required ColumnDefinition ColumnDefinition { get; set; }
    [Parameter] public RenderFragment? ChildContent { get; set; }
    protected override void OnInitialized()
    {
        this.Register?.Invoke(this.ColumnDefinition);
    }
}
Grid
@typeparam TItem
<h3>Grid</h3>
<CascadingValue Value="this.RegisterColumn">
        @ChildContent
        <div class="alert alert-info">
            Registered columns : @Columns.Count()
        </div>
</CascadingValue>
@code {
    [Parameter] public List<TItem>? DataItems { get; set; }
    [Parameter] public RenderFragment? ChildContent { get; set; }
    private readonly List<ColumnDefinition> Columns = new();
    private void RegisterColumn(ColumnDefinition columnDefinition)
    {
        if (!this.Columns.Any(item => item == columnDefinition ))
            Columns.Add(columnDefinition);
        StateHasChanged();
    }
}
				通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。



评论