For binding the collection to the Combobox in the DataGrid, you could refer to the following example. When editing the last row of cells to add a new row in the DataGrid, what you can do is:
- Make sure your DataGrid has CanUserAddRows=True.
- Make sure the class in the collectiuon that you are binding has a default constructor (no parameters).
- Make sure the collection type is not readonly.
For more information, you can refer here.
The code of xaml:
<Window.DataContext>
<local:ViewModel></local:ViewModel>
</Window.DataContext>
<Grid Background="AliceBlue" >
<DataGrid Name="dataGrid" ItemsSource="{Binding MyCollection}" BorderBrush="Black"
BorderThickness="1" AutoGenerateColumns="False" CanUserAddRows="True" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" Header="Name of person"/>
<DataGridTemplateColumn Header="Age of person" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=DataContext.Source1, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"
IsSynchronizedWithCurrentItem="False" IsHitTestVisible="False" SelectedValue="{Binding Age}" SelectedValuePath="Number" DisplayMemberPath="Number"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel>
<ComboBox ItemsSource="{Binding Path=DataContext.Source1, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"
SelectedValue="{Binding Age}" SelectedValuePath="Number" DisplayMemberPath="Number"
IsSynchronizedWithCurrentItem="False" IsEditable="True"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Binding="{Binding Salary}" Header="Persons salary"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
The code of xaml.cs:
using System.Windows;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System;
using System.Windows.Controls;
namespace DataGridCombobox
{
public partial class MainWindow : Window
{
private bool _justCreatedNewItem;
public MainWindow()
{
InitializeComponent();
dataGrid.BeginningEdit += (o, e) =>
{
if (_justCreatedNewItem)
{
dataGrid.CommitEdit(DataGridEditingUnit.Row, true);
_justCreatedNewItem = false;
}
};
dataGrid.InitializingNewItem += (o, e) => { _justCreatedNewItem = true; };
}
}
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged ;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
private ObservableCollection<MyClass> _myCollection { get; set; }
public ObservableCollection<MyClass> MyCollection
{
get { return _myCollection; }
set
{
_myCollection = value;
NotifyPropertyChanged(nameof(MyCollection));
}
}
private ObservableCollection<Source1> _source1 { get; set; }
public ObservableCollection<Source1> Source1
{
get { return _source1; }
set { _source1 = value; NotifyPropertyChanged(nameof(Source1)); }
}
public ViewModel()
{
_source1 = new ObservableCollection<Source1>();
_myCollection = new ObservableCollection<MyClass>();
SetupSource();
}
private void SetupSource()
{
_source1.Add(new Source1(2));
_source1.Add(new Source1(3));
_source1.Add(new Source1(5));
_source1.Add(new Source1(8));
_myCollection.Add(new MyClass("name1",12,30.3));
_myCollection.Add(new MyClass("name2",22,30.3));
_myCollection.Add(new MyClass("name3",32,30.3));
_myCollection.Add(new MyClass("name3",32,30.3));
}
}
public class Source1
{
public int Number { get; set; }
public Source1(int n)
{
Number = n;
}
}
public class MyClass
{
public string Name { get; set; }
public int Age { get; set; }
public double Salary { get; set; }
public MyClass()
{
}
public MyClass(string n, int a, double s)
{
Name = n;
Age = a;
Salary = s;
}
}
}
The picture of result:
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.