Reputation: 148
I am working on an MVVM WPF DataGrid application. I have a DataGrid and a multiselect CheckBox dropdown menu above it. Whenever I select an option in the menu, I want to add a column in the DataGrid. Is there any way to do that?
The code behind the ComboBox
Item Template looks like this:
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox
VerticalAlignment="Center"
ClickMode="Press"
Content="{Binding Position}"
IsChecked="{Binding IsSelected}" />
</DataTemplate>
</ComboBox.ItemTemplate>
Upvotes: 0
Views: 2733
Reputation: 29028
This is a simple example how to use a DataTable
as data source for a DataGrid
.
ViewModel.cs
class VeiwModel : INotifyPropertyChanged
{
// Let this property set() raise the INotifyPropertyChanged.PropertyChanged event
// if its value/instance will change after instantiation
public DataTable TableData { get; set; }
public ViewModel()
{
var changedTable = new DataTable();
AddColumn<int>("ID", changedTable);
AddColumn<string>("Username", changedTable);
AddColumn<string>("Mail", changedTable);
// Add column values in order of their columns
AddRow(changedTable, 1, "Me", "[email protected]");
// Update the DataGrid with changes
this.TableData = changedTable;
}
// Appends a new column.
// Use 'columnIndex' parameter to assign an other column index than the last
private void AddColumn<TData>(string columnName, DataTable targetDataTable, int columnIndex = -1)
{
DataColumn newColumn = new DataColumn(columnName, typeof(TData));
targetDataTable.Columns.Add(newColumn);
if (columnIndex > -1)
{
newColumn.SetOrdinal(columnIndex);
}
int newColumnIndex = targetDataTable.Columns.IndexOf(newColumn);
// Initialize existing rows with default value for the new column
foreach (DataRow row in targetDataTable.Rows)
{
row[newColumnIndex] = default(TData);
}
}
private void AddRow(DataTable targetDataTable, params object[] columnValues)
{
DataRow rowModelWithCurrentColumns = targetDataTable.NewRow();
targetDataTable.Rows.Add(rowModelWithCurrentColumns);
for (int columnIndex = 0; columnIndex < targetDataTable.Columns.Count; columnIndex++)
{
rowModelWithCurrentColumns[columnIndex] = columnValues[columnIndex];
}
}
}
MainWindow.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContex>
<DataGrid ItemsSource="{Binding TableData}" />
</Window>
Upvotes: 2
Reputation: 102
I have recently faced something similar in a C# uwp application. Here's what worked for me.
Firstly, I created a list to keep track of all checked checkboxes:
private List<CheckBox> checkedCheckboxes = new List<CheckBox>();
Then, I created the checkboxes and linked them to the same events like so (You probably have code for this part already):
foreach (foo blah in random)
{
var checkbox = new CheckBox(); //creating new checkbox
checkbox.Content = blah.name; //setting content
checkbox.Name = $"chk_{blah.name}"; //naming it
checkbox.Tag = "blah"; //adding the tag
checkbox.Checked += CheckBox_Checked; //adding the checked event
checkbox.Unchecked += CheckBox_Unchecked; //adding the unchecked event
ClassCheckboxes.Add(checkbox);
}
For the "CheckBox_Checked" event I did the following:
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
checkedCheckboxes.Add((CheckBox)sender);
//Here you can put some code to update your datagrid
}
And for the "CheckBox_Unchecked" event I did the following:
private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
{
checkedCheckboxes.Remove((CheckBox)sender);
//Here you can put some code to update your datagrid
}
To add a new column to your datagrid, you can refer to this answer. There are a few nice strategies there that may work for you. Here's the highest voted one for your convenience:
DataGridTextColumn textColumn = new DataGridTextColumn();
textColumn.Header = "First Name";
textColumn.Binding = new Binding("FirstName");
dataGrid.Columns.Add(textColumn);
Sorry if I've done something wrong here, this is my first time posting an answer so go easy on me :)
Upvotes: 1