I recently started using Syncfusion Blazor, but I'm having trouble understanding how the Template feature of the Listbox functions. I am trying to dynamically add components to a Listbox and pass the index of each new addition to the component. However, when I add a new component, all the indexes in the previous components also get updated. I need to be able to set the index for just one component.
@page "/test"
@using Syncfusion.Blazor.Buttons
@using Syncfusion.Blazor.DropDowns
<div class="container px-5">
<SfButton @onclick="AddMedia">Add Media</SfButton>
<SfListBox TValue="int[]" DataSource="@Data" TItem="ViewMedia" @ref="MediaListBoxObj">
<ListBoxFieldSettings></ListBoxFieldSettings>
<ListBoxTemplates TItem="ViewMedia">
<ItemTemplate>
<MediaCard media="new ViewMedia { ListIndex = MediaCount }" ></MediaCard>
</ItemTemplate>
</ListBoxTemplates>
<ListBoxSelectionSettings Mode="SelectionMode.Single"></ListBoxSelectionSettings>
</SfListBox>
</div>
@code {
// public ListData Model = new ListData();
SfListBox<int[], ViewMedia> MediaListBoxObj;
public List<ViewMedia> Data = new List<ViewMedia>
{
new ViewMedia{ ListIndex = 0}
};
int MediaCount = 0;
public List<ViewMedia> NewMediaItem { get; set; } = new List<ViewMedia>();
public List<ViewMedia> NewMedia()
{
NewMediaItem.Add(new ViewMedia { ListIndex = MediaCount});
return NewMediaItem;
}
private void AddMedia()
{
var newMediaItem = NewMedia();
MediaListBoxObj.AddItems(newMediaItem);
Data.Add(newMediaItem[0]);
MediaCount++;
NewMediaItem.Clear();
}
My MediaCard file:
<div class="AddMedia">
<div name="mediaAdd" class="container-fluid px-4">
<div class="form-row align-middle mb-2 pl-1">
<SfTextBox CssClass="e-filled" Placeholder="Provide a brief description" @bind-Value="media.Blurb"></SfTextBox>
</div>
<div class="form-row">
<label class="form-check-label">
Is there any blood or gore in the video?<span class="text-danger ml-1">*</span>
</label>
<div class="row">
<div class="form-check m-2 d-inline">
<SfRadioButton Label="No" Name="@media.ListIndex.ToString()" Value="0" Checked="@media.Gore"></SfRadioButton>
</div>
<div class="form-check m-2 d-inline">
<SfRadioButton Label="Yes" Name="@media.ListIndex.ToString()" Value="1" Checked="@media.Gore"></SfRadioButton>
</div>
</div>
</div>
</div>
</div>
@code {
[Parameter]
public ViewMedia media { get; set; }
}
I asked this question on the Syncfusion forums, and they got back to me with the following code which uses Observable Collection:
<div class="container px-5">
<SfButton @onclick="AddMedia">Add Media</SfButton>
<SfListBox TValue="int[]" DataSource="@Data" TItem="ViewMedia" @ref="MediaListBoxObj">
<ListBoxFieldSettings></ListBoxFieldSettings>
<ListBoxTemplates TItem="ViewMedia">
<ItemTemplate>
@{
var data = (context as ViewMedia);
<MediaCard media="new ViewMedia { ListIndex = data.ListIndex }"></MediaCard>
}
</ItemTemplate>
</ListBoxTemplates>
<ListBoxSelectionSettings Mode="SelectionMode.Single"></ListBoxSelectionSettings>
</SfListBox>
</div>
@code {
SfListBox<int[], ViewMedia> MediaListBoxObj;
public ObservableCollection<ViewMedia> Data { get; set; }
int MediaCount = 0;
protected override void OnInitialized()
{
this.Data = ViewMedia.getListData();
}
private void AddMedia()
{
MediaCount++;
this.Data.Add(new ViewMedia() { ListIndex = MediaCount });
}
public class ViewMedia
{
public int ListIndex { get; set; }
public int Gore { get; set; }
public string Blurb { get; set; }
public static ObservableCollection<ViewMedia> getListData()
{
ObservableCollection<ViewMedia> Data = new ObservableCollection<ViewMedia>();
Data.Add(new ViewMedia() { ListIndex = 0 });
return Data;
}
}
In case the above link fails, the above code can be downloaded here