Search code examples
c#wpfdata-bindingsyncfusiondatagridtemplatecolumn

GridTemplateColumn databinding to complex properties


I have 3 model classes as follows (Vegetable, Fruit and ItemInBasket):

public class Vegetable
    {
        string name;
        public string Name
        {
        get { return name; }
        set { name = value; }
    }


    public Vegetable(string _Name)
    {
        this.Name = _Name;
    }
}

public class Fruit
{
    string name;
    public string Name
    {
        get { return name; }
        set { name = value; }
    }


    public Fruit(string _Name)
    {
        this.Name = _Name;
    }
}

public class ItemInBasket
{
    string name;
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    object fruitorvegetable;
    public object FruitOrVegetable
    {
        get { return fruitorvegetable; }
        set { fruitorvegetable = value; }
    }

    int quantity;
    public int Quantity
    {
        get { return quantity; }
        set { quantity = value; }
    }

    public ItemInBasket(string _Name, object _FruitOrVegetable, int _Quantity)
    {
        this.Name = _Name;
        this.FruitOrVegetable = _FruitOrVegetable;
        this.quantity = _Quantity;
    }
}

My ViewModel is:

public class ViewModel
    {
    private ObservableCollection<object> _availableItems;
    public ObservableCollection<object> AvailableItems
    {
        get { return _availableItems; }
        set { _availableItems = value; }
    }

    private ObservableCollection<ItemInBasket> _itemsInBasket;
    public ObservableCollection<ItemInBasket> ItemsInBasket
    {
        get { return _itemsInBasket; }
        set { _itemsInBasket = value; }
    }

    public ViewModel()
    {
        _availableItems = new ObservableCollection<object>();
        _itemsInBasket = new ObservableCollection<ItemInBasket>();
        this.GenerateAvailableItems();
        this.GenerateItemsInBasket();
    }

    private void GenerateAvailableItems()
    {
        _availableItems.Add(new Vegetable("Broccoli"));         // index 0
        _availableItems.Add(new Vegetable("Kale"));             // index 1
        _availableItems.Add(new Vegetable("Spinach"));          // index 2
        _availableItems.Add(new Vegetable("Carrots"));          // index 3
        _availableItems.Add(new Vegetable("Garlic"));           // index 4

        _availableItems.Add(new Fruit("Apple"));                // index 5
        _availableItems.Add(new Fruit("Orange"));               // index 6
        _availableItems.Add(new Fruit("Pear"));                 // index 7
        _availableItems.Add(new Fruit("Cherry"));               // index 8
        _availableItems.Add(new Fruit("Grape"));                // index 9
    }

    private void GenerateItemsInBasket()
    {
        _itemsInBasket.Add(new ItemInBasket("Apples",_availableItems[5],3));
        _itemsInBasket.Add(new ItemInBasket("Kale", _availableItems[1], 10));
        _itemsInBasket.Add(new ItemInBasket("Grape", _availableItems[9], 2));
        _itemsInBasket.Add(new ItemInBasket("Carrots", _availableItems[3], 1));
    }
}

I am trying to be able to modify the FruitOrVegetable inside of each ItemInBasket displayed in the datagrid but I have an issue with the data binding. I am using Syncfusion datagrid but I think it shouldnt affect anything.

    <syncfusion:SfDataGrid AutoGenerateColumns="False" SelectionMode="Single"
                    AllowEditing="True" AllowDeleting="True" ItemsSource="{Binding ItemsInBasket,Source={StaticResource viewModel}}">
        <syncfusion:SfDataGrid.Columns>

            <syncfusion:GridTemplateColumn MappingName="FruitOrVegetable" HeaderText="Order">
                <syncfusion:GridTemplateColumn.EditTemplate>
                    <DataTemplate>
                        <ComboBox IsEditable="True" DisplayMemberPath="Name"  SelectedValuePath="Name"
                                  Text="{Binding FruitOrVegetable.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                  ItemsSource="{Binding AvailableItems, Source={StaticResource viewModel}}"/>
                    </DataTemplate>
                </syncfusion:GridTemplateColumn.EditTemplate>
                <syncfusion:GridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}" />
                    </DataTemplate>
                </syncfusion:GridTemplateColumn.CellTemplate>
            </syncfusion:GridTemplateColumn>

            <syncfusion:GridNumericColumn HeaderText="Quantity" MappingName ="Quantity"/>

        </syncfusion:SfDataGrid.Columns>
    </syncfusion:SfDataGrid>

Solution

  • Your requirement to display the modified value of the FruitOrVegetable in SfDataGrid can be achieved by binding the SelectedValue property of ComboBox. Please refer to the below code snippet,

                            <ComboBox IsEditable="True" DisplayMemberPath="Name"  SelectedValuePath="Name"
                                      SelectedValue="{Binding Name}"
                                      Text="{Binding FruitOrVegetable.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                      ItemsSource="{Binding AvailableItems, Source={StaticResource viewModel}}"/>