GridTemplateColumn 数据绑定到复杂属性

GridTemplateColumn databinding to complex properties

我有 3 个模型 类 如下(蔬菜、水果和 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;
    }
}

我的 ViewModel 是:

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

我正在尝试修改数据网格中显示的每个 ItemInBasket 内的 FruitOrVegetable,但我遇到了数据绑定问题。我正在使用 Syncfusion 数据网格,但我认为它不会影响任何东西。

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

这就是我们所说的“界面”派上用场的地方。这使您确信属性确实存在于该对象上。将其视为 class 和接口之间的契约,总是包含一些属性。
您可以了解更多 here

你可以这样定义一个接口

public interface INamedItem
{
    string Name {get;set;}   
}

现在使用此接口代替 object 类型(首先在您的蔬菜和水果中实现它们 class)以便您可以轻松绑定到它(以及许多其他好处)

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


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

public class Fruit: INamedItem
{
    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; }
    }

    INamedItem 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, INamedItem _FruitOrVegetable, int _Quantity)
    {
        this.Name = _Name;
        this.FruitOrVegetable = _FruitOrVegetable;
        this.quantity = _Quantity;
    }
}

对于您的可用物品,它变为:

private ObservableCollection<INamedItem> _availableItems;
    public ObservableCollection<INamedItem> AvailableItems
    {
        get { return _availableItems; }
        set { _availableItems = value; }
    }

现在按照您在代码中的方式正常添加,因此不再对其进行更改并检查它是否有效:)

您需要在SfDataGrid中显示FruitOrVegetable的修改值,可以通过绑定ComboBox的SelectedValue属性来实现。请参考以下代码片段,

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