Answered by:
Binding DataGrid to empty DataTable

Question
-
Hi,
I'm very much new to WPF and am finding it a bit tricky to find my way in the mass of (not always great) documentation. Right now I'm struggling to get the grid to display it's UI when bound to an empty datatable.
In my XAML:
<DataGrid Name="grid" ItemsSource="{Binding}" />
In my code-behind (MainWindow constructor, following InitializeComponent):
var dt = new DataTable(); dt.Columns.Add("col1"); dt.Columns.Add("col2"); //var r = dt.Rows.Add("toto", "tata"); grid.DataContext = dt;
If I comment out the line that adds a row to the table, all is well -- the grid generates columns and displays UI. But if the table is empty, the grid renders a thin horizontal white rectangle with no column names and it doesn't seem possible to interact with this at all.
As it happens, I want the grid to be empty by default, so I need to somehow get the grid to play along. If anyone knows why this happens and what to do to solve it, I'd much appreciate the help!
Wednesday, September 1, 2010 8:15 AM
Answers
-
Hi,
By default WPF Datagrid AutoGenerateColumns = true, In this case the columns will not be generated if there is no rows exists in the DataTable.
If you want to have the Empty Grid with columns then you must set WPF Datagrid AutoGenerateColumns = false and you have to add the columns to the Datagrid manually.
You can also go through the following post regarding this issue.
Also, when you assign the DataTable to DataGrid, It should be like this
grid.DataContext = dt.DefaultView;
Hope this helps!
regards,
Vimal
Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This will help other members to find the solution easily.- Proposed as answer by Mustehsan Ikram Wednesday, September 1, 2010 8:57 AM
- Marked as answer by Jie Bao Wednesday, September 8, 2010 10:14 AM
Wednesday, September 1, 2010 8:55 AM -
Thanks Vimal. I still find it weird to ignore the columns that are definitely there just because there are no rows. In fact, I don't see why the grid should even consider the rows with respect to the behavior of AutoGenerateColumns. But I can simply set AGC to false and use a foreach to add the grid columns corresponding to the DataTable columns myself. It's rather easy in this case as all the columns happen to be of type string.
- Marked as answer by Jie Bao Wednesday, September 8, 2010 1:21 PM
Wednesday, September 8, 2010 1:05 PM
All replies
-
Hi,
By default WPF Datagrid AutoGenerateColumns = true, In this case the columns will not be generated if there is no rows exists in the DataTable.
If you want to have the Empty Grid with columns then you must set WPF Datagrid AutoGenerateColumns = false and you have to add the columns to the Datagrid manually.
You can also go through the following post regarding this issue.
Also, when you assign the DataTable to DataGrid, It should be like this
grid.DataContext = dt.DefaultView;
Hope this helps!
regards,
Vimal
Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This will help other members to find the solution easily.- Proposed as answer by Mustehsan Ikram Wednesday, September 1, 2010 8:57 AM
- Marked as answer by Jie Bao Wednesday, September 8, 2010 10:14 AM
Wednesday, September 1, 2010 8:55 AM -
Hi Dag,
Have you checked out ksvimal's solution yet? Did it work for you?
Below code you may need:
<DataGrid Name="grid" ItemsSource="{Binding}" CanUserAddRows="False" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="col1" Binding="{Binding col1}"/> <DataGridTextColumn Header="col2" Binding="{Binding col2}"/> </DataGrid.Columns> </DataGrid>
code:
var dt = new DataTable(); dt.Columns.Add("col1"); dt.Columns.Add("col2"); //var r = dt.Rows.Add("toto", "tata"); grid.DataContext = dt.DefaultView;
Sincerely,
Bob Bao
MSDN Subscriber Support in Forum
If you have any feedback on our support, please contact msdnmg@microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.Friday, September 3, 2010 6:38 AM -
Hi Dag,
How about your problem? If you need help, please feel free to let me know.
Sincerely,
Bob Bao
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Are you looking for a typical code sample? Please download all in one code framework !Wednesday, September 8, 2010 10:15 AM -
Thanks Vimal. I still find it weird to ignore the columns that are definitely there just because there are no rows. In fact, I don't see why the grid should even consider the rows with respect to the behavior of AutoGenerateColumns. But I can simply set AGC to false and use a foreach to add the grid columns corresponding to the DataTable columns myself. It's rather easy in this case as all the columns happen to be of type string.
- Marked as answer by Jie Bao Wednesday, September 8, 2010 1:21 PM
Wednesday, September 8, 2010 1:05 PM -
Hi Bob. The reply was indeed useful. However, there seems to be a problem with e-mail notification - I had not received any, and so thought noone had answered. Now I came back to the forums to reply to a question I myself posted that I just found the solution to, just in case someone might use it, and to my surprise saw my previous question (this one) marked as answered.Wednesday, September 8, 2010 1:07 PM
-
Hi The Dag,
Actually, the issue you asked in this thread has been concerned. As ksvimal said, the link on the connect site has been replied, it is 'By Design'. But thank you for this feedback. If you have any problem, please feel free to let me know.
Sincerely,
Bob Bao
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Are you looking for a typical code sample? Please download all in one code framework !Wednesday, September 8, 2010 1:21 PM -
Hi There,
I am having similar issue. I am new to WPF.
Here is my code,
----------------------------------------------------------------------------------------------------------
<DataGrid Height="187" HorizontalAlignment="Left" Margin="24,80,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="220" ItemsSource="{Binding}" MinColumnWidth="108" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="120" FontWeight="Bold" />
<DataGridTextColumn Header="Price" FontWeight="Bold" />
</DataGrid.Columns>
</DataGrid>--------------
public static ObservableCollection<Level> levels = new ObservableCollection<Level>();
......
........
levels.Add(new Level { Name = "ABC", Price = 100.5 });
levels.Add(new Level { Name = "XYZ", Price = 100.1 });
levels.Add(new Level { Name = "PQR", Price = 100.2 });
dataGrid1.ItemsSource = levels;-----------------------------------------------------------------
How can I use DefaultView () or DefaultIfEmpty( ) method with this type (ObservableCollection<Level>) of variable. I tried this,
dataGrid1.ItemsSource = levels.DefaultIfEmpty();
But it didn't work.
Please let me know if anyone know about this.
Thanks
Nas
Monday, November 1, 2010 8:24 PM -
I am working on MVVM and have a work around for this.
I am attaching a behavior to the datagrid and listening to the itemschanged to generate the columns manually.
Note: The data grid is read only here.
xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<WpfToolkit:DataGrid ItemsSource="{Binding Employees}"
AutoGenerateColumns="True"
HeadersVisibility="{Binding HeadersVisibility}"
IsReadOnly="True">
<Interactivity:Interaction.Behaviors>
<Behavior:DataGridAutoGeneratedColumnsBehavior/>
</Interactivity:Interaction.Behaviors>
</WpfToolkit:DataGrid>
........Behavior
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.ItemContainerGenerator.ItemsChanged += ItemContainerGeneratorItemsChanged;
}
void ItemContainerGeneratorItemsChanged(object sender, System.Windows.Controls.Primitives.ItemsChangedEventArgs e)
{
var itemsource = this.AssociatedObject.ItemsSource as DataView;
if (itemsource == null) return;
// If item Source is null, datagrid does not display the columns. Below code will manually add the columns.
if (itemsource.Count == 0)
{
AssociatedObject.Columns.Clear();
foreach (var dataGridcolumn in from DataColumn column in itemsource.Table.Columns
select new DataGridTextColumn
{
Header = column.Caption,
MinWidth = column.MaxLength
})
{
dataGridcolumn.Width = new DataGridLength(dataGridcolumn.MinWidth, DataGridLengthUnitType.Star);
AssociatedObject.Columns.Add(dataGridcolumn);
}
}
//Remove the columns if they are not auto generated.
else if (AssociatedObject.Columns.All(dataGridColumn => dataGridColumn.IsAutoGenerated == false))
AssociatedObject.Columns.Clear();
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.ItemContainerGenerator.ItemsChanged -= ItemContainerGeneratorItemsChanged;
}
Friday, December 10, 2010 7:34 AM