namespace BlazorTreeView.ViewModels;
public class Comment
{
public IList<Comment> Comments = new List<Comment>();
public string? Text { set; get; }
} using BlazorTreeView.ViewModels;
namespace BlazorTreeView.Pages;
public partial class TreeView
{
private IReadOnlyDictionary<string, object> ChildrenHtmlAttributes { get; } =
new Dictionary<string, object>(StringComparer.Ordinal)
{
{ "style", "list-style: none;" },
};
private IList<Comment> Comments { get; } =
new List<Comment>
{
new()
{
Text = "پاسخ یک",
},
new()
{
Text = "پاسخ دو",
Comments =
new List<Comment>
{
new()
{
Text = "پاسخ اول به پاسخ دو",
Comments =
new List<Comment>
{
new()
{
Text = "پاسخی به پاسخ اول پاسخ دو",
},
},
},
new()
{
Text = "پاسخ دوم به پاسخ دو",
},
},
},
new()
{
Text = "پاسخ سوم",
},
};
}
/// <summary>
/// A custom DntTreeView
/// </summary>
public partial class DntTreeView<TRecord>
{ /// <summary>
/// The treeview's self-referencing items
/// </summary>
[Parameter]
public IEnumerable<TRecord>? Items { set; get; } /// <summary>
/// The treeview item's template
/// </summary>
[Parameter]
public RenderFragment<TRecord>? ItemTemplate { set; get; } /// <summary>
/// The content displayed if the list is empty
/// </summary>
[Parameter]
public RenderFragment? EmptyContentTemplate { set; get; } public class Comment
{
public IList<Comment> Comments = new List<Comment>();
public string? Text { set; get; }
} /// <summary>
/// The property which returns the children items
/// </summary>
[Parameter]
public Expression<Func<TRecord, IEnumerable<TRecord>>>? ChildrenSelector { set; get; } <DntTreeView
TRecord="Comment"
Items="Comments"
ChildrenSelector="m => m.Comments" public partial class DntTreeView<TRecord>
{
private Expression? _lastCompiledExpression;
internal Func<TRecord, IEnumerable<TRecord>>? CompiledChildrenSelector { private set; get; }
// ...
protected override void OnParametersSet()
{
if (_lastCompiledExpression != ChildrenSelector)
{
CompiledChildrenSelector = ChildrenSelector?.Compile();
_lastCompiledExpression = ChildrenSelector;
}
}
} @namespace BlazorTreeView.Pages.Components
@typeparam TRecord
@if (Items is null || !Items.Any())
{
@EmptyContentTemplate
}
else
{
<CascadingValue Value="this">
<ul @attributes="AdditionalAttributes">
@foreach (var item in Items)
{
<DntTreeViewChildrenItem TRecord="TRecord" ParentItem="item"/>
}
</ul>
</CascadingValue>
} @namespace BlazorTreeView.Pages.Components
@typeparam TRecord
<li @attributes="@SafeOwnerTreeView.ChildrenHtmlAttributes" @key="ParentItem?.GetHashCode()">
@if (SafeOwnerTreeView.ItemTemplate is not null && ParentItem is not null)
{
@SafeOwnerTreeView.ItemTemplate(ParentItem)
}
@if (Children is not null)
{
<ul>
@foreach (var item in Children)
{
<DntTreeViewChildrenItem TRecord="TRecord" ParentItem="item"/>
}
</ul>
}
</li> /// <summary>
/// A custom DntTreeView
/// </summary>
public partial class DntTreeViewChildrenItem<TRecord>
{
/// <summary>
/// Defines the owner of this component.
/// </summary>
[CascadingParameter]
public DntTreeView<TRecord>? OwnerTreeView { get; set; }
private DntTreeView<TRecord> SafeOwnerTreeView =>
OwnerTreeView ??
throw new InvalidOperationException("`DntTreeViewChildrenItem` should be placed inside of a `DntTreeView`.");
/// <summary>
/// Nested parent item to display
/// </summary>
[Parameter]
public TRecord? ParentItem { set; get; }
private IEnumerable<TRecord>? Children =>
ParentItem is null || SafeOwnerTreeView.CompiledChildrenSelector is null
? null
: SafeOwnerTreeView.CompiledChildrenSelector(ParentItem);
} <div class="card" dir="rtl">
<div class="card-header">
DntTreeView
</div>
<div class="card-body">
<DntTreeView
TRecord="Comment"
Items="Comments"
ChildrenSelector="m => m.Comments"
style="list-style: none;"
ChildrenHtmlAttributes="ChildrenHtmlAttributes">
<ItemTemplate Context="record">
<div class="card mb-1">
<div class="card-body">
<span>@record.Text</span>
</div>
</div>
</ItemTemplate>
<EmptyContentTemplate>
<div class="alert alert-warning">
There is no item to display!
</div>
</EmptyContentTemplate>
</DntTreeView>
</div>
</div>
برچسب:
نویسنده: دانلودی