We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

SfDataGrid ComboBoxColumn for nested grids

I have a nested table for which I want to show a editable, ComboBox Column. The Itemsource for the ComboBox column is a ObservableCollection property from the child table model .
The ComboBox model has the following properties: ItemId, ItemCode, ItemName. The ComboBox should show the ItemCode, also in the child table model I have a property that should hold the selected value SelName.
I've set MappingName="SelName" SelectedValuePath="ItemName" DisplayMemberPath="ItemName", but the ComboBox seems to be empty, by empty I mean that when I click on it, the drop down is blank.
Is there something I'm missing?
Thanks,
Lucian

3 Replies

JN Jayaleshwari N Syncfusion Team December 13, 2018 11:52 AM UTC

Hi Lucian,  
  
Thanks for contacting Syncfusion Support.  
  
We have checked your query “SfDatagrid combo Box column for Nested grids” and we have prepared the sample based on your requirement.   
  
Code snippet C#:  ComboBox column model class. 
  
public class ItemDetails : INotifyPropertyChanged  
{  
    private string itemCode;  
  
    public string ItemCode  
    {  
        get  
        {  
            return itemCode;  
        }  
        set  
        {  
            itemCode = value;  
            RaisePropertyChanged("ItemCode");  
        }  
    }  
    private string itemName;  
  
    public string ItemName  
    {  
        get  
        {  
            return itemName;  
        }  
        set  
        {  
            itemName = value;  
            RaisePropertyChanged("ItemName");  
        }  
    }  
    private int itemID;  
  
    public int ItemID  
    {  
        get  
        {  
            return itemID;  
        }  
        set  
        {  
            itemID = value;  
            RaisePropertyChanged("ItemID");  
        }  
    }  
}  
  
Code snippet C#: Nested data grid model class that has SelName property.  
  
public class OrderDetails:INotifyPropertyChanged  
{  
    private string selName;  
    public string SelName  
    {  
        get  
        {  
            return selName;  
        }  
        set  
        {  
            selName = value;  
            RaisePropertyChanged("SelName");  
        }  
    }  
}  
  
Code snippet C#: Combo box ItemsSource population. 
 
public void PopulateItemDetails()  
{  
    itemDetails = new ObservableCollection<ItemDetails>();  
    itemDetails.Add(new ItemDetails() { ItemName = "SfDatagrid", ItemID = 01, ItemCode = "AAA" });  
    itemDetails.Add(new ItemDetails() { ItemName = "SfCellGrid", ItemID = 02, ItemCode = "AAB" });  
    itemDetails.Add(new ItemDetails() { ItemName = "SfComnboBox", ItemID = 03, ItemCode = "AAC"});  
    itemDetails.Add(new ItemDetails() { ItemName = "SfTreeGrid", ItemID = 04, ItemCode = "AAD" });   
}  
private ObservableCollection<ItemDetails> itemDetails;  
  
public ObservableCollection<ItemDetails> ItemDetails  
{  
    get  
    {  
        return itemDetails;  
    }  
    set  
    {  
        itemDetails = value;  
    }  
}          
   
Code snippet XAML: GridComboBoxColumn binding 
  
<Window.Resources>  
        <local:ViewModel x:Key="viewModel"/>  
    </Window.Resources>  
 
 <syncfusion:SfDataGrid x:Name="dataGrid" Grid.Column="0"  
                        AutoGenerateColumns="False" AllowEditing="True"  
                        AutoGenerateRelations="False"  
                        AllowResizingColumns="False"  
                        HideEmptyGridViewDefinition="True"  
                        ItemsSource="{Binding Path=OrdersDetails}"  
                        NavigationMode="Cell"  
                        ShowGroupDropArea="True">  
    <syncfusion:SfDataGrid.DetailsViewDefinition>  
        <syncfusion:GridViewDefinition RelationalColumn="OrderDetails">  
            <syncfusion:GridViewDefinition.DataGrid>  
                <syncfusion:SfDataGrid x:Name="FirstDetailsViewGrid" AllowEditing="True" >  
                    <syncfusion:SfDataGrid.Columns>  
                    <syncfusion:GridComboBoxColumn ItemsSource="{Binding ItemDetails,Source={StaticResource viewModel}}"   
                                                MappingName="SelName"    
                                                DisplayMemberPath="ItemName"   
                                                SelectedValuePath="ItemName" />  
                   </syncfusion:SfDataGrid.Columns>  
                </syncfusion:SfDataGrid> 
             </syncfusion:GridViewDefinition.DataGrid> 
          <syncfusion:GridViewDefinition > 
     </syncfusion:SfDataGrid.DetailsViewDefinition>                      
</syncfusion:SfDataGrid> 
 
We have attached the sample for your reference and you can download the same from the following location. 
 
Please let us know if you need any further assistance.  
  
Regards, 
Jayaleshwari N 



LM Lucian Mihai December 13, 2018 03:12 PM UTC

Thank you for your solution but I'm having problems with the editable part: when I enter text, the data is set to null during the CurrentCellEndEdit event.


JN Jayaleshwari N Syncfusion Team December 14, 2018 12:11 PM UTC

Hi Lucian,  
  
Thank you for your update.  
  
We have analyzed your reported query “When enter the text in the combobox and the data is set to null” and this is the behavior of combo box. When IsEditable is true, the entered text will be the comboBox value. Whenever we enter the invalid data (which does not present in the comboBox underlying source), the selected value of the combobox is to be null. So that it is showing the null on the current cell end edit event. And you can see the wrongly entered text in the combobox when again you go to the edit mode of the cell.  
  
In GridComboBox column, we have used ContentControl as DisplayElement and ComboBox as EditElement., which means ComboBox is loaded only when we enter into EditMode.  And You can resolve this by using the below solutions.  
  
Solution 1:  
And you can reset the previous selected value when we enter the wrong data in the combobox by overriding the combobox renderer.  
  
public class SfDataGridBehavior : Behavior<SfDataGrid>  
{  
    SfDataGrid dataGrid = null;  
    GridComboboxColumnRendererExt comboBoxRenderer = new GridComboboxColumnRendererExt();  
    protected override void OnAttached()  
    {  
        dataGrid = this.AssociatedObject as SfDataGrid;  
        dataGrid.DetailsViewLoading += DataGrid_DetailsViewLoading;  
        base.OnAttached();  
    }  
  
    private void DataGrid_DetailsViewLoading(object sender, DetailsViewLoadingAndUnloadingEventArgs e)  
    {  
           if (e.DetailsViewDataGrid.CellRenderers["ComboBox"] != comboBoxRenderer)  
                e.DetailsViewDataGrid.CellRenderers["ComboBox"] = comboBoxRenderer;  
    }  
}  
  
 
public class GridComboboxColumnRendererExt:GridCellComboBoxRenderer  
{  
    int selectedIndex = 0;  
    public GridComboboxColumnRendererExt():base()  
    {  
  
    }  
         
    protected override void OnUnwireEditUIElement(ComboBox uiElement)  
    {  
        if(uiElement.SelectedIndex == -1 && uiElement.SelectedValue== null)  
        {  
            uiElement.SelectedIndex = selectedIndex;  
        }  
        base.OnUnwireEditUIElement(uiElement);  
    }  
  
    protected override void OnEditElementLoaded(object sender, RoutedEventArgs e)  
    {  
        var combobox = sender as ComboBox;  
        if (combobox != null && combobox.SelectedIndex > -1)  
            selectedIndex = combobox.SelectedIndex;  
        base.OnEditElementLoaded(sender, e);  
    }  
}  
  
  
Solution 2:  
  
And you can able to add the entered value in the combo box by using CurrentCellValidatingEvent the below code snippets.  
  
public class SfDataGridBehavior : Behavior<SfDataGrid>  
{  
    SfDataGrid dataGrid = null;  
    protected override void OnAttached()  
    {  
        dataGrid = this.AssociatedObject as SfDataGrid;  
        dataGrid.DetailsViewLoading += DataGrid_DetailsViewLoading;  
        base.OnAttached();  
    }  
  
    private void DataGrid_DetailsViewLoading(object sender, DetailsViewLoadingAndUnloadingEventArgs e)  
    {  
              (dataGrid.DetailsViewDefinition[0] asGridViewDefinition).DataGrid.CurrentCellValidating += DetailsViewDataGrid_CurrentCellValidating;  
           
    }  
     
private void DetailsViewDataGrid_CurrentCellValidating(object sender, CurrentCellValidatingEventArgs e)  
{  
    var detailsViewDataGrid = e.OriginalSender as DetailsViewDataGrid;  
    var currentColumn = detailsViewDataGrid.CurrentColumn;  
    var currentCell = detailsViewDataGrid.SelectionController.CurrentCellManager.CurrentCell;  
    if (currentColumn is GridComboBoxColumn)  
    {  
        var combobox = ((currentCell as DataColumnBase).ColumnElement as GridCell).Content asComboBox;  
        var itemName = combobox.Text;  
        var dataContext = (dataGrid.DataContext as ViewModel).ItemDetails;  
        var itemDetails = dataContext.FirstOrDefault(item => item.ItemName == itemName);  
  
        if (itemDetails == null)  
        {  
            dataContext.Add(new ItemDetails() { ItemName = itemName, ItemID = new Random().Next(6, 100), ItemCode = "itemName" });  
        }  
        e.NewValue = combobox.Text;  
        combobox.ItemsSource = dataContext;  
    }  
}  
 
We have attached the sample for your reference and you can download the same from the following location. 
  
Please let us know if you need any further assistance on this.  
  
Regards, 
Jayaleshwari N 


Loader.
Live Chat Icon For mobile
Up arrow icon