Search code examples
listboxblazorsyncfusion

Syncfusion Blazor ListBox Template


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

Solution

  • 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