Reputation: 343
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
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
Upvotes: 1