How to programmatically add columns to wpf datagrid with MVVM?
I found the solution.
The Answer is simple.
- Define a
DataTable
in the view model - Define columns (In my case I had to define columns
programmatically
within aforeach
loop) - Add rows
- Then bind the DataTable for the
ItemsSource
property of the datagrid. (Make sure that theAutoGeneratedColumns=True
)
My View Model
private DataTable sizeQuantityTable;
public DataTable SizeQuantityTable
{
get
{
return sizeQuantityTable;
}
set
{
sizeQuantityTable = value;
NotifyPropertyChanged("SizeQuantityTable");
}
}
I have assinged dummy data
in the constructor
public MainViewModel()
{
this.SizeQuantityTable = new DataTable();
DataColumn sizeQuantityColumn = new DataColumn();
sizeQuantityColumn.ColumnName = "Size Quantity";
this.SizeQuantityTable.Columns.Add(sizeQuantityColumn);
DataColumn sColumn = new DataColumn();
sColumn.ColumnName = "S";
this.SizeQuantityTable.Columns.Add(sColumn);
DataColumn mColumn = new DataColumn();
mColumn.ColumnName = "M";
this.SizeQuantityTable.Columns.Add(mColumn);
DataRow row1 = this.SizeQuantityTable.NewRow();
row1[sizeQuantityColumn] = "Blue";
row1[sColumn] = "12";
row1[mColumn] = "15";
this.SizeQuantityTable.Rows.Add(row1);
DataRow row2 = this.SizeQuantityTable.NewRow();
row2[sizeQuantityColumn] = "Red";
row2[sColumn] = "18";
row2[mColumn] = "21";
this.SizeQuantityTable.Rows.Add(row2);
DataRow row3 = this.SizeQuantityTable.NewRow();
row3[sizeQuantityColumn] = "Green";
row3[sColumn] = "24";
row3[mColumn] = "27";
this.SizeQuantityTable.Rows.Add(row3);
DataRow row4 = this.SizeQuantityTable.NewRow();
row4[sizeQuantityColumn] = "Yellow";
row4[sColumn] = "30";
row4[mColumn] = "33";
this.SizeQuantityTable.Rows.Add(row4);
}
My view
<Window x:Class="Pivot.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Pivot.ViewModels"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.DataContext>
<vm:MainViewModel />
</Grid.DataContext>
<DataGrid
ItemsSource="{Binding SizeQuantityTable}"
AutoGenerateColumns="True"
/>
</Grid>
</Window>
How to programmatically add rows to DataGrid in C#?
Here's you can do it better way by binding a source to datagridview
// Creating DataSource here as datatable having two columns
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name");
// Adding the rows in datatable
for (int iCount = 1; iCount < 6; iCount++)
{
var row = dt.NewRow();
row["ID"] = iCount;
row["Name"] = "Name " + iCount;
dt.Rows.AddRow(row);
}
DataGridView dgv = new DataGridView();
// Set AutoGenerateColumns true to generate columns as per datasource.
dgv.AutoGenerateColumns = true;
// Finally bind the datasource to datagridview.
dgv.DataSource = dt;
In Case you are using WPF DataGrid
you can bind it like this way-
dgv.DataContext = employeeData.DefaultView;
and in
XAML
<DataGrid Name="dgv" ItemsSource="{Binding}">
Dynamically add a column in WPF DataGrid
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", "me@mail.com");
// 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>
WPF How to add rows to a DataGrid at runtime then add text to these rows
After agreeing with comments, if you still want to look into.... below is simple example for your XAML
Create a simple class with all your data column headers
public class dataGriditems
{
public string StepNumber { get; set; }
public string Requirement { get; set; }
public string Description { get; set; }
}
In the XAML add the binding for each column and ensure the binding name is same as the class properties, that you are going add as item source (In this case the above class)
<DataGridTextColumn Header="Step Number" Binding="{Binding StepNumber}" />
<DataGridTextColumn Header="Requirement" Binding="{Binding Requirement}" />
<DataGridTextColumn Header="Description" Binding="{Binding Description}" Width="*" />
In the XAML set AutoGenerateColumns="False" for data grid.
<DataGrid x:Name="dataGrid" Margin="10,167,11,10"
SelectionChanged="dataGrid_SelectionChanged" MinColumnWidth="22" AutoGenerateColumns="False">
In the code, create a simple list of objects of above defined class and assign the list to dataGrid.ItemsSource
as shown below
List<dataGriditems> items = new List<dataGriditems>();
items.Add(new dataGriditems() { StepNumber = "one", Requirement = "req1", Description = "desc1"});
items.Add(new dataGriditems() { StepNumber = "two", Requirement = "req2", Description = "desc2" });
items.Add(new dataGriditems() { StepNumber = "three", Requirement = "req3", Description = "desc3" });
items.Add(new dataGriditems() { StepNumber = "four", Requirement = "req4", Description = "desc4" });
dataGrid.ItemsSource = items;
How do I add columns and cells in a row to a datagrid programmatically?
There is a difference in adding rows and columns. Try doing the following:
private void Output<T>(List<T> objList)
{
foreach (var prop in T.GetProperties())
{
var column = prop.Name;
CarDetailsGrid.Columns.Add(new DataGridTextColumn()
{
Header = column,
Binding = new Binding(column)
});
}
if (objList != null && objList.Any())
{
foreach(var currObj in objList)
{
CarDetailsGrid.Items.Add(currObj);
}
}
}
Add items to datagrid programmatically
You can add custom items to your DataGrid by creating a class which holds the item's values in it:
Class Item
Private _name As String
Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
Me._name = value
End Set
End Property
//Some other properties
End Class
Now you can create your DataGrid column like this:
Dim myColumn As New DataGridTextColumn()
myColumn.Header = "Name"
myColumn.Binding = New Binding("Name")
dataGrid.Columns.Add(myColumn)
You can now add rows by adding items to your DataGrid:
Dim item = New Item With {.Name = "Terry Adams"}
dataGrid.Items.Add(item)
I hope this helps.
Adding Rows and Columns to a WPF DataGrid at Run-Time
public static void Display_Grid(DataGrid d, List<string> S1)
{
ds = new DataSet();
DataTable dt = new DataTable();
ds.Tables.Add(dt);
DataColumn cl = new DataColumn("Item Number", typeof(string));
cl.MaxLength = 200;
dt.Columns.Add(cl);
int i = 0;
foreach (string s in S1)
{
DataRow rw = dt.NewRow();
rw["Item Number"] = S1[i];
i++;
}
d.ItemsSource = ds.Tables[0].AsDataView();
}
Related Topics
Use Own Icomparer<T> with Linq Orderby
Return View as String in .Net Core
Swap Two Variables Without Using a Temporary Variable
Entity Framework Refresh Context
Can Timers Get Automatically Garbage Collected
Convert Any Object to a Byte[]
SQL Query Slow in .Net Application But Instantaneous in SQL Server Management Studio
Is There a Reason Image.Fromfile Throws an Outofmemoryexception for an Invalid Image Format
Webbrowser.Drawtobitmap() or Other Methods
How to Post an Array of Complex Objects with JSON, Jquery to ASP.NET MVC Controller
Extension Methods Must Be Defined in a Non-Generic Static Class
How to Update a Table Using Oledb Parameters
How to Calculate the Angle Between a Line and the Horizontal Axis