简体   繁体   中英

How to bind a list of a custom object to a DataGridComboboxColumn in WPF?

I found some examples on this site, but I couldn't find anything which I can use In my case.

I have a DataGrid with AutoGeneratedColumn="False" and ViewModel which is bind to the DataContext of my Window, in which the DataGrid is located. In my ViewModel I have a List of a data structure called Model which is bind to the ItemsSource property of my DataGrid .

The model contains an Enum . I was able to generate a DataGridComboboxColumn for the enum, but I don't know how to archive the same for a list of objects.

Here is my Model.cs class.

public class Model
{
    public CType Type { get; set; }
    public Person Person { get; set; }
    public Condition Condition { get; set; }
}

public class Person
{
    public List<Trait> Traits { get; set; }
    public string Name { get; set; }
}

public class Condition
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Value { get; set; }
}

public class Trait
{
    public string Name { get; set; }
    public List<Reason> Reasons { get; set; }
}

public class Reason
{
    public string Name { get; set; }
}

Here is my ViewModel.cs class, with pre-populated objects of Type Model .

public class ViewModel
{
    //Bind to Grid - ItemsSource
    public ObservableCollection<Model> Models { get; set; }

    //Possible ComboboxValues for Column: Model.Person
    public ObservableCollection<Person> Persons { get; set; }

    //Possible ComboboxValues for Column: Model.Condition
    public ObservableCollection<Condition> Conditions { get; set; }

    public ViewModel()
    {
        Models = new ObservableCollection<Model>();

        #region Model1
        Model model = new Model();
        model.Condition = new Condition()
        {
            Id = 1,
            Name = "Hallo",
            Value = 5
        };
        model.Type = CType.One;
        model.Person = new Person()
        {
            Name = "Peter",
            Traits = new List<Trait>()
            {
                new Trait()
            {
                Name = "Trait 1",
                Reasons = new List<Reason>()
                {
                    new Reason() { Name = "Reason 1" },
                    new Reason() { Name = "Reason 2" }
                }
            },
            new Trait()
            {
                Name = "Trait 2",
                Reasons = new List<Reason>()
                {
                    new Reason() { Name = "Reason 3" },
                    new Reason() { Name = "Reason 4" }
                }
            }
            }
        };
        #endregion

        #region Model2 
        Model model2 = new Model();
        model2.Condition = new Condition()
        {
            Id = 1,
            Name = "Welt",
            Value = 5
        };
        model2.Type = CType.Three;
        model2.Person = new Person()
        {
            Name = "Manuel",
            Traits = new List<Trait>()
            {
                new Trait()
                {
                    Name = "Trait 3",
                    Reasons = new List<Reason>()
                    {
                        new Reason() { Name = "Reason 5" },
                        new Reason() { Name = "Reason 6" }
                    }
                },
                new Trait()
                {
                    Name = "Trait 4",
                    Reasons = new List<Reason>()
                    {
                        new Reason() { Name = "Reason 7" },
                        new Reason() { Name = "Reason 8" }
                    }
                }
            }
        };
        #endregion

        Persons = new ObservableCollection<Person>()
        {
            model.Person, model2.Person
        };

        Conditions = new ObservableCollection<Condition>()
        {
            model.Condition, model2.Condition
        };

        Models.Add(model);
        Models.Add(model2);
    }
}

And this is my Window.xaml file with the working enum example. Last but not least you have the set the DataContext property to a new instance of the ViewModel class in code behind.

<Window x:Class="WpfApp2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp2"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.Resources>
    <ObjectDataProvider x:Key="myEnumData"
            MethodName="GetValues" 
            ObjectType="{x:Type sys:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:CType" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</Window.Resources>
<Grid>
    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Models}">
        <DataGrid.Columns>
            <DataGridComboBoxColumn 
                Header="Enum"
                ItemsSource="{Binding Source={StaticResource myEnumData}, Mode=OneWay}"
                SelectedValueBinding="{Binding Path=Type}">
            </DataGridComboBoxColumn>

            <!--ComboBox for Persons-->
            <DataGridComboBoxColumn>

            </DataGridComboBoxColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

Try this:

<DataGridComboBoxColumn Header="Person" DisplayMemberPath="Name" SelectedItemBinding="{Binding Person}">
    <DataGridComboBoxColumn.ElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding DataContext.Persons, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding DataContext.Persons, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM