Add One Or Many Rows To a List Property of a Table In a DataGrid?

I currently have a Data Grid for a table of Staff members. Each staff member can have 0, 1 or many Clients attached to them. Currently I am trying to display them in a ComboBox in the Details View to allow the user to select them.

I have several questions:

1: How I can bind the client to the parent list property?
2. Is there a better way then to use the Add a New Row function with a ComboBox to attached numerous Clients to a Staff member?
3. Instead of having a details view/sub grid, could I instead somehow not have to use a Subgrid and allow the user to add multiple Clients in the main data grid via a combobox with multiple selects? If so how would multiple selects work with the database in terms of telling it to add/delete many people at once?


add client.png

public class StaffModel:PersonModel{

    public List<ClientModel>? Clients { get; set; }

    public StaffModel() : base() { }

}

My Staff Xaml page:

<dataGrid:SfDataGrid

    x:Name="MainDataGrid"

    Grid.Row="2"

    Grid.ColumnSpan="2"

    AddNewRowPosition="Top"

    AllowEditing="True"

    AutoGenerateColumns="False"

    AutoGenerateRelations="True"

    ColumnWidthMode="Star"

    GridLinesVisibility="Both"

    Loaded="OnMainGridLoad">

    <dataGrid:SfDataGrid.Columns>

        <dataGrid:GridTextColumn HeaderText="First Name" MappingName="FirstName" />

        <dataGrid:GridTextColumn HeaderText="Last Name" MappingName="LastName" />

        <dataGrid:GridTextColumn MappingName="Nickname" />

        <dataGrid:GridTextColumn MappingName="Phone" />

        <dataGrid:GridTextColumn MappingName="EmailAddress" />

</dataGrid:SfDataGrid.Columns>

<dataGrid:SfDataGrid.DetailsViewDefinition>

    <dataGrid:GridViewDefinition RelationalColumn="Clients">

        <dataGrid:GridViewDefinition.DataGrid>

            <dataGrid:SfDataGrid

                x:Name="ClientsDataGrid"

                AddNewRowPosition="Top"

                AllowDeleting="True"

                AllowEditing="True"

                AutoGenerateColumns="False"

                ColumnWidthMode="Star"

                GridLinesVisibility="Both">

                <dataGrid:SfDataGrid.Columns>

                    <dataGrid:GridTemplateColumn HeaderText="Client" MappingName="Id">

                        <dataGrid:GridTemplateColumn.CellTemplate>

                            <DataTemplate>

                                <TextBlock

                                    VerticalAlignment="Center"

                                    Text="{Binding FullName}"

                                    TextAlignment="Center" />

                            </DataTemplate>

                        </dataGrid:GridTemplateColumn.CellTemplate>


                        <dataGrid:GridTemplateColumn.EditTemplate>

                            <DataTemplate>


                                <editors:SfComboBox

                                    x:Name="comboBox"

                                    Width="250"

                                    ItemsSource="{Binding DataContext.Clients, ElementName=RootGrid}"

                                    PlaceholderText="Select a client"

                                    SelectedItem="{Binding Clients.Client, Mode=TwoWay}"

                                    SelectionMode="Multiple" />

                            </DataTemplate>

                        </dataGrid:GridTemplateColumn.EditTemplate>

                    </dataGrid:GridTemplateColumn>

                </dataGrid:SfDataGrid.Columns>

            </dataGrid:SfDataGrid>

        </dataGrid:GridViewDefinition.DataGrid>

    </dataGrid:GridViewDefinition>

</dataGrid:SfDataGrid.DetailsViewDefinition>

</dataGrid:SfDataGrid>


8 Replies 1 reply marked as answer

EE Elavazhagan Elangovan Syncfusion Team July 8, 2025 05:21 PM UTC

Hi Alfred Smith,


We have investigated the reported scenario. We are currently analyzing the scenario and we need some time to validate. We will provide further updates on July 10, 2025.


Regards,

Elavazhagan E 



AS Alfred Smith replied to Elavazhagan Elangovan July 11, 2025 11:57 AM UTC

Ok thanks for the update :)



SB Sweatha Bharathi Syncfusion Team July 11, 2025 02:48 PM UTC

Alfred Smith,

Queries

Responses

How I can bind the client to the parent list property?


You can bind the client to the parent relationship by declaring a collection of clients in the model class. In XAML, you can define the relationship details accordingly.

To define Master-Details View relationships in SfDataGrid, follow these steps:

1. In the model class, declare a property of type IEnumerable (e.g., ObservableCollection<ClientModel>) to represent the child collection:

 

C# Code snippet to Bind the relationship client to Parent (staff):

    public class PersonModel : INotifyPropertyChanged

    {

        private string _firstName;

        private string _lastName;

        private string _nickname;

        private string _phone;

        private string _emailAddress;

        private int _staffId;

        private string clientName;

        private ObservableCollection<ClientModel> _clientmodel;

 

        public string FirstName

        {

            get => _firstName;

            set

            {

                if (_firstName != value)

                {

                    _firstName = value;

                    OnPropertyChanged(nameof(FirstName));

                }

            }

        }

 

        public string ClientName

        {

            get => clientName;

            set

            {

                if (clientName != value)

                {

                    clientName = value;

                    OnPropertyChanged(nameof(ClientName));

                }

            }

        }

 

        public string LastName

        {

            get => _lastName;

            set

            {

                if (_lastName != value)

                {

                    _lastName = value;

                    OnPropertyChanged(nameof(LastName));

                }

            }

        }

 

        public string Nickname

        {

            get => _nickname;

            set

            {

                if (_nickname != value)

                {

                    _nickname = value;

                    OnPropertyChanged(nameof(Nickname));

                }

            }

        }

 

        public string Phone

        {

            get => _phone;

            set

            {

                if (_phone != value)

                {

                    _phone = value;

                    OnPropertyChanged(nameof(Phone));

                }

            }

        }

 

        public string EmailAddress

        {

            get => _emailAddress;

            set

            {

                if (_emailAddress != value)

                {

                    _emailAddress = value;

                    OnPropertyChanged(nameof(EmailAddress));

                }

            }

        }

 

        public int StaffId

        {

            get => _staffId;

            set

            {

                if (_staffId != value)

                {

                    _staffId = value;

                    OnPropertyChanged(nameof(StaffId));

                }

            }

        }

 

        public ObservableCollection<ClientModel> ClientDetails

        {

            get { return _clientmodel; }

            set

            {

                _clientmodel = value;

                OnPropertyChanged(nameof(ClientDetails));

            }

        }

 

        public PersonModel()

        {

 

        }

 

        public event PropertyChangedEventHandler? PropertyChanged;

 

        protected virtual void OnPropertyChanged(string propertyname) =>

           PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));

    }

 

 

2. In XAML, define a GridViewDefinition and set the RelationalColumn property to the name of the child collection (e.g., "ClientDetails")

Xaml Code snippet to enable the relations:

 

<dataGrid:SfDataGrid  x:Name="MainDataGrid"

               AddNewRowPosition="Top"

               AllowEditing="True"

               AutoGenerateColumns="False"

               AutoGenerateRelations="False"

               ColumnWidthMode="Star"

               DataContext="{StaticResource ViewModel}"

               GridLinesVisibility="Both"

               ItemsSource="{Binding Staffs}">

 

     <dataGrid:SfDataGrid.Columns>

         <dataGrid:GridNumericColumn HeaderText="ID" MappingName="StaffId"/>

         <dataGrid:GridTextColumn HeaderText="First Name" MappingName="FirstName" />

         <dataGrid:GridTextColumn HeaderText="Last Name" MappingName="LastName" />

         <dataGrid:GridTextColumn MappingName="Phone" />

         <dataGrid:GridTextColumn MappingName="EmailAddress" />

     </dataGrid:SfDataGrid.Columns>

 

     <dataGrid:SfDataGrid.DetailsViewDefinition>

         <dataGrid:GridViewDefinition RelationalColumn="ClientDetails">

             <dataGrid:GridViewDefinition.DataGrid>

                 <dataGrid:SfDataGrid

                     x:Name="ClientsDataGrid"

                     AddNewRowPosition="Top"

                     AllowDeleting="True"

                     AllowEditing="True"

                     AutoGenerateColumns="False"

                     ColumnWidthMode="Star"

                     GridLinesVisibility="Both"

                     AddNewRowInitiating="ClientsDataGrid_AddNewRowInitiating">

 

                     <dataGrid:SfDataGrid.Columns>

                         <dataGrid:GridTextColumn HeaderText="Client Name" MappingName="FullName"/>

                     </dataGrid:SfDataGrid.Columns>

                 </dataGrid:SfDataGrid>

             </dataGrid:GridViewDefinition.DataGrid>

         </dataGrid:GridViewDefinition>

     </dataGrid:SfDataGrid.DetailsViewDefinition>

 </dataGrid:SfDataGrid>

 

 

Is there a better way then to use the Add a New Row function with a ComboBox to attached numerous Clients to a Staff member?


To meet your requirement—where each staff member can have zero, one, or many clients—you can use the MasterDetailsView to display client details without using a ComboBox.

This feature works based on key-value relationships. Specifically, it matches the parent StaffId with the corresponding ClientId in the child table.

When a match is found, the related clients are displayed under the respective staff member.

 

when adding a new client, you can retrieve the parent StaffId and assign it to the new client's Id to maintain the relationship using AddNewRowInitiating event.

 

C# code snippet to retrieve the parent ID:

 

private void ClientsDataGrid_AddNewRowInitiating(object sender, AddNewRowInitiatingEventArgs e)

 {

     //Maintain unique ID for new staff added via  AddNewRow in child datagrid

     var clientGrid = e.OriginalSender as DetailsViewDataGrid;

 

     var getFirstData = clientGrid.RowGenerator.Items.FirstOrDefault(item => item.RowType == RowType.DefaultRow);

     if (getFirstData != null)

     {

         var getUniqueID = getFirstData.RowData as ClientModel;

 

         if (getUniqueID != null)

         {

             var getNewRow = e.NewObject as ClientModel;

             //Define the unique ID when new row added in Child Grid for same staff. 

             getNewRow.Id = getUniqueID.Id;

         }

     }

 }



Instead of having a details view/sub grid, could I instead somehow not have to use a Subgrid and allow the user to add multiple Clients in the main data grid via a combobox with multiple selects? If so how would multiple selects work with the database in terms of telling it to add/delete many people at once?

Without using a ComboBox column, you can use the above approach. This will help display the data more effectively, and it also supports multiple operations such as: Multiple selection Delete operations by enabling AllowDeleting property, and  Adding new rows using AddNewRow or adding adding new data manually .


Image Reference:

A screenshot of a computer

AI-generated content may be incorrect.


UG Link: MasterDetailsView

Find the sample demo in the attachment and let us know if you have any concerns on this.

If this post is helpful, please consider Accepting it as the solution so that other members can locate it more quickly.


Attachment: Sample_6c108842.zip


AS Alfred Smith replied to Sweatha Bharathi July 11, 2025 05:03 PM UTC

Hi I am having some issues adapting your code.


For the clients I use a ComboBox grid column whose source is a list of Clients, however I am having issues mapping it correctly.


 Error: Converter failed to convert value of type 'null' to type 'Int32'; BindingExpression: Path='Id' DataItem='App.ViewModels.Data.People.ClientViewModel'; target element is 'Syncfusion.UI.Xaml.Editors.SfComboBox' (Name='null'); target property is 'SelectedValue' (type 'Object').


This is what my details view looks like atm:

<dataGrid:SfDataGrid.DetailsViewDefinition>
    <dataGrid:GridViewDefinition RelationalColumn="Clients">
        <dataGrid:GridViewDefinition.DataGrid>
            <dataGrid:SfDataGrid
                x:Name="ClientsDataGrid"
                AddNewRowInitiating="SubDataGrid_AddNewRowInitiating"
                AddNewRowPosition="Top"
                AllowDeleting="True"
                AllowEditing="True"
                AutoGenerateColumns="False"
                ColumnWidthMode="Star"
                GridLinesVisibility="Both">
                <dataGrid:SfDataGrid.Columns>
                    <dataGrid:GridComboBoxColumn
                        x:Name="ClientComboBox"
                        DisplayMemberPath="FullName"
                        HeaderText="Client"
                        ItemsSource="{Binding DataContext.ClientList, ElementName=RootGrid}"
                        MappingName="Id" />

                </dataGrid:SfDataGrid.Columns>
            </dataGrid:SfDataGrid>
        </dataGrid:GridViewDefinition.DataGrid>
    </dataGrid:GridViewDefinition>
</dataGrid:SfDataGrid.DetailsViewDefinition>


SB Sweatha Bharathi Syncfusion Team July 14, 2025 02:22 PM UTC

Alfred Smith, 

Currently we are analyzing the reported scenario, we need time to validate, we will provide an further update on July 16, 2025.


SB Sweatha Bharathi Syncfusion Team July 16, 2025 12:45 PM UTC

Alfred Smith,


Based on the information provided, we understand that you require a ComboBox with multi-selection support. However, adding a MultiSelect feature directly within a ComboBoxColumn is currently not supported. As an alternative, you can use a GridTemplateColumn and configure the edit element as a SfComboBox.

Code snippet to configure the edit element as SfComboBox:

<dataGrid:SfDataGrid.DetailsViewDefinition>

    <dataGrid:GridViewDefinition RelationalColumn="ClientDetails">

        <dataGrid:GridViewDefinition.DataGrid>

            <dataGrid:SfDataGrid   x:Name="ClientsDataGrid"

                                                    AddNewRowPosition="Top"

                                                    AllowDeleting="True"

                                                    AllowEditing="True"

                                                   AutoGenerateColumns="False"

                                                   ColumnWidthMode="Star"

                                                   GridLinesVisibility="Both"

                                                   AddNewRowInitiating="ClientsDataGrid_AddNewRowInitiating">

                <dataGrid:SfDataGrid.Columns>                                 

                    <dataGrid:GridTemplateColumn MappingName="FullName"

                                                                               HeaderText="ClientDetails">

                        <dataGrid:GridTemplateColumn.CellTemplate>

                             <DataTemplate>

                                   <TextBlock Text="{Binding FullName}"></TextBlock>

                              </DataTemplate>

                        </dataGrid:GridTemplateColumn.CellTemplate>

                        <dataGrid:GridTemplateColumn.EditTemplate>

                            <DataTemplate>

                                <editors:SfComboBox x:Name="sfComboBox"

                                                                       DisplayMemberPath="FullName"

                                                                        DataContext="{Binding AllClients , Source={StaticResource ViewModel}}"

                                                                      Loaded="OnLoaded"

                                                                      SelectionMode="Multiple"

                                                                      Width="300"

                                                                      SelectionChanged="OnSelectionChanged" />

                            </DataTemplate>

                      </dataGrid:GridTemplateColumn.EditTemplate>

                 </dataGrid:GridTemplateColumn>

             </dataGrid:SfDataGrid.Columns>

        </dataGrid:SfDataGrid>

 </dataGrid:GridViewDefinition.DataGrid>



To achieve different ItemsSource values for combobox based on the parent row, you can handle the Loaded event of the SfComboBox. In this event, you can retrieve the current data row using the FindParent method. Based on the row's ID, you can then retrieve the matching values from the ComboBox's DataContext. Using these values, you can bind the appropriate ItemsSource to the SfComboBox.

Code snippet to bind different Itemsource based on parent row:

private void OnLoaded(object sender, RoutedEventArgs e)

{

    var comboBox = sender as SfComboBox;

    if (comboBox == null) return;

 

    // Retrieve the DataRow

    var dataRow = FindParent<DataGridRowControl>(comboBox);

    if (dataRow == null) return;

 

    var record = dataRow.DataContext;

    if ( record == null || record is not ClientModel person)

        return;

 

    int staffId = person.Id;

 

    string fullName = person.FullName;

 

    // Assuming the DataContext of the ComboBox is a collection of staff or similar

    var dataContextItems = comboBox.DataContext as IEnumerable<object>;

    if (dataContextItems == null) return;

 

    // Filter items where the staffId matches

    var filteredItems = dataContextItems

        .OfType<ClientModel>() // Replace with your actual item type

        .Where(item => item.Id == staffId) // Adjust property name as neeqaded

        .ToList();

    if (filteredItems.Count > 0)

        comboBox.ItemsSource = filteredItems;

 

    // Split the names by "-" and trim whitespace

    var names = fullName.Split('-')

                        .Select(name => name.Trim())

                        .ToList();

 

    // Match against your available list (filteredItems or full list)

    var matchedClients = filteredItems

        .Where(client => names.Contains(client.FullName))

        .ToList();

 

    if (matchedClients.Count > 0)

    {

        foreach (var item in matchedClients)

        {

            comboBox.SelectedItems.Add(item);

        }

    }

  

}

public static T FindParent<T>(DependencyObject child) where T : DependencyObject

 {

     DependencyObject parentObject = VisualTreeHelper.GetParent(child);

     if (parentObject == null) return null;

 

     if (parentObject is T parent)

         return parent;

 

     return FindParent<T>(parentObject);

 }



Additionally, to display the selected items in a TextBlock, you can use the SelectionChanged event of the SfComboBox. Within this event, retrieve the current data row using the FindParent method, access the FullName property, and assign the selected items values to it accordingly.

Code snippet to display the SelectedItems in TextBlock:

private void OnSelectionChanged(object sender, ComboBoxSelectionChangedEventArgs e)

{

    var comboBox = sender as SfComboBox;

    if (comboBox == null)

        return;

 

    var dataRow = FindParent<DataGridRowControl>(comboBox);

    if (dataRow == null)

        return;

 

    var selectedItems = comboBox.SelectedItems

        .OfType<ClientModel>()

        .ToList();

 

    var record = dataRow.DataContext;

 

    if (record == null || record is not ClientModel person)

        return;

 

    if (selectedItems.Any())

    {

        // Join all selected FullNames with a separator (e.g., comma or dash)

        person.FullName = string.Join(" - ", selectedItems.Select(item => item.FullName));

    }

}


Find the modified sample in the attachment and let us know if you have any concerns on this.

If this post is helpful, please consider Accepting it as the solution so that other members can locate it more quickly.


Attachment: Sample_248a7838.zip

Marked as answer

AS Alfred Smith replied to Sweatha Bharathi July 17, 2025 04:47 PM UTC

Hi thanks for the reply I played around with the code you supplied but having looked at it, I think having the DetailsView/Grid is unneeded.

I would like to do the following instead:
- Keep everything on the same grid without a details grid.

- There would be a template column that in the cell view shows a button that shows the amount of Clients associated with the staff member.

- When the user clicks the button, it then displays a combobox that supports multiple selection in the edit view.


These images represent what I am trying to achieve: 


Image 1 - Before going into edit mode


before_menu.png


Image 2 - After click on the button


menu_open_b.png



SB Sweatha Bharathi Syncfusion Team July 18, 2025 02:01 PM UTC

Alfred Smith,

We have created a new forum for your last update since this is a new query. We request that you have a further follow-up on a new forum.

Loader.
Up arrow icon