WPF DataGrid DataGridTemplateColumn ComboBox ItemSource

Matt Ellenburg picture Matt Ellenburg · Jul 2, 2013 · Viewed 19.8k times · Source

I'm trying to create a very simple CRUD WPF application. I have a datagrid with 2 columns, ID, and Category. For category, I want to be able to select from a list when adding and editing. Here's what I have so far in the xaml:

<DataGrid Name="dataGridBudgetEntries" AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="True" RowEditEnding="dataGridBudgetEntries_RowEditEnding">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding ID}" Header="ID" IsReadOnly="True"></DataGridTextColumn>
        <DataGridTemplateColumn Header="Category">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding CategoryName}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox></ComboBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

In the code behind, I have the following:

public MainWindow()
{
    InitializeComponent();

    dataGridBudgetEntries.ItemsSource = FinancialManagementDatabase4ME.BLL.GetBudgetEntriesForDataGrid();
    List<Category> categories = FinancialManagementDatabase4ME.BLL.GetCategories();
}

The grid is populating and the display value for category is correct. I cannot figure out how to define the combobox in the datatemplate so that it displays the selected value along with a list of other categories. I've seen tons of examples but cannot get any to work.

Answer

Nathan picture Nathan · Jul 2, 2013
 <DataGrid AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="True" ItemsSource="{Binding Entries}" RowEditEnding="dataGridBudgetEntries_RowEditEnding">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding ID}" Header="ID" IsReadOnly="True"></DataGridTextColumn>
        <DataGridTemplateColumn Header="Category">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Category}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding Categories}"></ComboBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>


public MainWindow()
{
    InitializeComponent();
    this.DataContext = new MyViewModel();
}

public class MyViewModel : ViewModelBase
{
    public MyViewModel()
    {
        this.Entries = FinancialManagementDatabase4ME.BLL.GetBudgetEntriesForDataGrid();
        this.Categories = FinancialManagementDatabase4ME.BLL.GetCategories();
    }

    private ObservableCollection<BudgetEntries> entries;
    public ObservableCollection<BudgetEntries> Entries
    {
        get
        {
            return this.entries;
        }

        set
        {
            if (value != this.entries)
            {
                this.entries = value;
                this.OnPropertyChanged("Entries");
            }
        }
    }

    private ObservableCollection<Category> categories;
    public ObservableCollection<Category> Categories
    {
        get
        {
            return this.categories;
        }

        set
        {
            if (value != this.categories)
            {
                this.categories = value;
                this.OnPropertyChanged("Categories");
            }
        }
    }
}

public class BudgetEntries : ViewModelBase
{
    private string id;
    public string Id
    {
        get
        {
            return this.id;
        }

        set
        {
            if (value != this.id)
            {
                this.id = value;
                this.OnPropertyChanged("Id");
            }
        }
    }

    private string category;
    public string Category
    {
        get
        {
            return this.category;
        }

        set
        {
            if (value != this.category)
            {
                this.category = value;
                this.OnPropertyChanged("Category");
            }
        }
    }
}