Gisiota
Gisiota

Reputation: 343

Bind data into multicolum datagrid-combobox wpf

I found this tutorial online which is exactly what I am trying to do, but the tutorial does not explain how to load data from code behind into the combobox. any idea how I can acheive this?

Basically I want a multicolumn combobox in a datagrid, and when the user selects an item, it displays only one of the values and not both.

<DataGrid x:Name="DGOrders" Margin="30" AutoGenerateColumns="False" >
<DataGrid.Columns>
    <DataGridTextColumn Binding="{Binding OrderID}" Header="Order ID" />
    <DataGridTemplateColumn Header="User" Width="200">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ComboBox SelectedValue="{Binding UserID}" SelectedValuePath="UserID" DisplayMemberPath="CompanyName" HorizontalContentAlignment="Stretch" ItemsSource="{Binding}" >
                    <ComboBox.ItemContainerStyle>
                        <Style TargetType="{x:Type ComboBoxItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate>
                                        <Grid>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="Auto"/>
                                                <ColumnDefinition Width="*"/>
                                                <ColumnDefinition Width="*"/>
                                            </Grid.ColumnDefinitions>
                                            <TextBlock Margin="5" Grid.Column="0" Text="{Binding UserID}"/>
                                            <TextBlock Margin="5" Grid.Column="1" Text="{Binding CompanyName}"/>
                                            <TextBlock Margin="5" Grid.Column="2" Text="{Binding UserName}"/>
                                        </Grid>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </ComboBox.ItemContainerStyle>
                </ComboBox>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

Upvotes: 0

Views: 964

Answers (1)

SamTh3D3v
SamTh3D3v

Reputation: 9944

I am not sure about what you meant by displaying only one of the values and not both, but i hope that explain it self once i show you how to properly bind the properties in the DataGrid, first of all you need to make sure that your model looks something like this :

public class Order
{
    public string OrderId { get; set; }
    public string SelectedUserId { get; set; }
}

public class User
{
    public string UserId { get; set; }
    public string CompanyName { get; set; }
    public string UserName { get; set; }
}

then in the code behind create two collectionw to hold the users list and the orders list which represent the DataContext for the ComboBox and the DataGrid:

  private ObservableCollection<Order> _ordersCollection = new ObservableCollection<Order>()
    {
        new Order()
        {
            OrderId = "1",
            SelectedUserId = "2"
        } ,new Order()
        {
            OrderId = "2",
            SelectedUserId = "3"
        }
    };

    public ObservableCollection<Order> OrdersCollection
    {
        get
        {
            return _ordersCollection;
        }

        set
        {
            if (_ordersCollection == value)
            {
                return;
            }

            _ordersCollection = value;
            OnPropertyChanged();
        }
    }


    private ObservableCollection<User> _usersCollection = new ObservableCollection<User>()
    {
        new User()
        {
            UserId = "1",
            UserName = "Name1",
            CompanyName = "Company1"
        } ,new User()
        {
            UserId = "2",
            UserName = "Name2",
            CompanyName = "Company2"
        } ,new User()
        {
            UserId = "3",
            UserName = "Name3",
            CompanyName = "Company3"
        }
    };


    public ObservableCollection<User> UsersCollection
    {
        get
        {
            return _usersCollection;
        }

        set
        {
            if (_usersCollection == value)
            {
                return;
            }

            _usersCollection = value;
            OnPropertyChanged();
        }
    }

you may consider implementing the INotifyPropertyChanged interface so that the UI will be notified each time the collection is updated.

Now in the UI, make sure your main window's DataContext is set to the codebehind using this

DataContext="{Binding RelativeSource={RelativeSource Self}}"

then properly bind the Properties:

<Grid>
    <DataGrid x:Name="DGOrders" Margin="30" AutoGenerateColumns="False" ItemsSource="{Binding OrdersCollection}">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding OrderId}" Header="Order ID" />
            <DataGridTemplateColumn Header="User" Width="200" >
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox SelectedValue="{Binding SelectedUserId}" SelectedValuePath="UserId" DisplayMemberPath="CompanyName" HorizontalContentAlignment="Stretch" ItemsSource="{Binding DataContext.UsersCollection,ElementName=DGOrders}" >
                            <ComboBox.ItemContainerStyle>
                                <Style TargetType="{x:Type ComboBoxItem}">
                                    <Setter Property="Template">
                                        <Setter.Value>
                                            <ControlTemplate>
                                                <Grid>
                                                    <Grid.ColumnDefinitions>
                                                        <ColumnDefinition Width="Auto"/>
                                                        <ColumnDefinition Width="*"/>
                                                        <ColumnDefinition Width="*"/>
                                                    </Grid.ColumnDefinitions>
                                                    <TextBlock Margin="5" Grid.Column="0" Text="{Binding UserId}"/>
                                                    <TextBlock Margin="5" Grid.Column="1" Text="{Binding CompanyName}"/>
                                                    <TextBlock Margin="5" Grid.Column="2" Text="{Binding UserName}"/>
                                                </Grid>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                            </ComboBox.ItemContainerStyle>
                        </ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
        </DataGrid>
</Grid>

you will end up with something like this

enter image description here

Upvotes: 1

Related Questions