2
votes

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.

2

2 Answers

3
votes
 <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");
            }
        }
    }
}
0
votes

You need to inherit the INotifyPropertyChanged interface in your data item class (the type you are using to give each row data), and use the PropertyChangedEventHandler to be able to notify the datagrid which item should be selected according to the property of your data type, as well as update the property on that type, for that row, whenever a selection is made in the combobox. Take a look at this blog entry titled: WPF Datagrid Combobox Column at: http://www.dylansweb.com. It will be just what you need I believe.