Adding data to DataGridView Column wise - winforms

I want to add data in Data Grid View column wise.
I am adding the column at runtime and then i want to add data to it.
Also is it possible that the columns resize themselves to fit the window.
eg-If there are 10 columns then 10 columns should fill the window else if there are 5 columns then 5 columns should fill the window

Here is the code for a simple example doing what you want. It is from the code behind for a simple form with one DataGridView control on it.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
BindingList<BindingClass> data = new BindingList<BindingClass>() {
new BindingClass { Name = "joe", Surname = "bloggs" },
new BindingClass { Name = "sue", Surname = "bloggs" } };
dataGridView1.DataSource = data;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
}
}
public class BindingClass
{
public string Name { get; set; }
public string Surname { get; set; }
}
}
I've created a custom object to use for my data - this is where your list goes. All the public properties of lists bound to the DataGridView's datasource get created as columns - you can then hide unwanted columns.
In my example I've chosen to use a BindingList<T> rather than a List<T> - this is generally preferred since it gives you editing and can be extended to support sorting.
I also set the AutoSizeColumnsMode of the grid to Fill - there are several other options including setting the width or fill properties of each column individually, and these can also be set through the designer.
I don't recommend using a ListView since it doesn't offer automatic databinding.

Related

Binding XamDataGrid field definitions to view model

I am attempting to build an application that will show different columns in the same XamDataGrid for different Projects. Here is an example:
public class Project
{
public ICollection<Person> People { get; private set; }
public string DisplaySpec { get; private set; }
}
public class Person{
{
public Name Name { get; set; }
}
public class Name
{
... a bunch of dynamic properties that vary by project...
}
I can look up the properties for each Name dynamically with no problem, and if I write Xaml and compile it in the actual executable I can display them. But each project has a different list of fields to bind to, and I want them to be able to inject the field names to display.
Is there any easy manner in which I can allow them to specify the name of the fields that they want to use?
The fields themselves can't be bound. Your best options are to either to auto generate the fields or to have a method in code that would add the fields needed dynamically. If you are looking to have a solution that you can use a binding in XAML with you could put the logic to add the fields into a behavior on the grid that exposes a property that you could bind your list to.
To auto generate the fields you would need to set the AutoGenerateFields on the FieldLayoutSettings to True.

Generate dynamic columns and bind data dynamically for WPF Datagrid or DevexGridcontrol

I have the following data structure:
public class StudentScore {
public string ScoreValue{ get; set; }
}
public class Student {
public string StudentName { get; set; }
//Scores.Count will be = EndDate-StartDate
public ObservableCollection<StudentScore> Scores { get;set; }
}
ObservableCollection<Student> Students { get; set; }
public DateTime StartDate { get; set; } //Can be changed by user dynamically
public DateTime EndDate { get; set; } //Can be changed dynamically
What i am interested to achieve in WPF DataGrid/DevExpress GridControl is as follows:
Column 1 is always fixed, which is student name and remaining columns will be only based on the number of Scores and each row should populate the student name and scores.
And each cell should have a two way binding where user can edit the score to reflect back in the actual VM property.
I tried to set the AutoGenerateColumns property to true - it generates only two columns because I have only StudentName and Scores properties. So i need some thing that can generate columns from collection for each row.
You can bind grid columns via the GridControl.ColumnsSource property.
Please review this approach detailed description in the following help article: Binding to a Collection of Columns.

Wpf ListBox with text and images

I need to create an ordering list having as elements strings and images (some items are text, other -images). I have to configure this list from code behind, not in xaml.
I created a class :
public class SimpleChoicePair
{
public SimpleChoice Choice { get; set; }
public FrameworkElement Content { get; set; }
}
where as Content I have TextBlock or Image objects. My listbox looks like:
var listboxChoices = new ListBox();
var list = new ObservableCollection();
listboxChoices.DisplayMemberPath = "Content";
listboxChoices.ItemsSource = choicesList;
But the items in the list display only the class name of TextBlock or Image. How can I display the uiElements themselves? Thanks for any help
If i am right you are looking about the itemtemplateselector on the basis of your content for e.g if content type text then show the textbock or if its image type then show me the images. see below exampbles.
http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemtemplateselector.aspx
http://www.switchonthecode.com/tutorials/wpf-tutorial-how-to-use-a-datatemplateselector

Data binding access in xaml vs in code behind - Linq to XML?

I have a listbox that binds to and displays the Name elements from an XML file. When a listbox item is selected, I want to display the Price value associated with this item in a textblock. How do I retrieve the Price programmatically (meaning not in the xaml file but in code behind)? Thanks.
XML file has these nodes:
<Product>
<Name>Book</Name>
<Price>7</Price>
</Product>
I use Linq and do the select with an anonymous type. If the easiest way to access the field programmatically is through a named type, please show me how.
Here's how I bind in xaml (using a data template for each listbox item that contains):
<TextBlock Text = "{Binding Name}" />
Here's the code-behind function where I want to retrieve the Price:
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// how do I get the value of Price of the selected item here?
}
Please note that I want to access Price in this function, NOT in xaml!
First of all you probably don't even need LINQ as you can do a lot of things with XmlDocuments including doing selection via XPath (also in Bindings).
Secondly converting anonymous types to named types is trivial, if you have
select new { Name = ..., Price = ... }
You just need a class with the respective properties
select new Product { Name = ..., Price = ... }
public class Product
{
public string Name { get; set; }
public string Price { get; set; } // Datatype is up to you...
}
Thirdly you can make do without named types using dynamic.
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = (ListBox)sender;
// Named type:
Product item = (Product)listBox.SelectedItem;
// Anonymous type:
dynamic item = listBox.SelectedItem;
// <Do something with item.Price, may need to cast it when using dynamic>
// e.g. MessageBox.Show((string)item.Price);
}
You should be able to retrieve the selected item from the SelectionChangedEventArgs parameter. i.e.
var item = e.AddedItems.First();
Refer to this post - bind textblock to current listbox item in pure xaml, you can get the name both in xaml and code-behind using XmlDataProvider.

Cannot edit values of DataGridView bound to a BindingList

I have trouble editing a databound bindinglist. Let me illustrate it with the following:
Say I have the Person class:
public Class Person{
private string m_firstname;
private string m_lastname;
public string FirstName{get;set;}
public string LastName{get;set;}
public Person{ ... }
}
I then have a containing class called Population:
public class Population{
private BindingList<Person> m_lstPerson = new BindingList<Person>();
private string m_countryName;
public BindingList<Person> ListPerson{get; set;}
public string CountryName { get; set; }
}
I then have on one form a first datagridview with DataSource = m_lstPopulation (BindingList). The binding works like a charm when working with the Population objects. When I double click, it opens up a dialog form showing the object details. One tab in the details holds a datagridview bound to that population's ListPerson.
The second datagridview displays fine. However, I cannot edit or add cells in this datagridview. None of the columns is set to read-only. In fact, both datagridview have just about the same parameters.
What am I missing? It seems that a lock has been placed on the Population object so that its inner fields cannot be edited...
Please advise. Thanks.
First verify that these grid properties are set:
ReadOnly = false;
AllowUserToAddRow = true;
EditMode = ;
If that doesn't work then you may be getting stuck in edit mode... It sounds like you have some custom behavior on your grid ("When I double click, it opens up a dialog form showing the object details.")...
For this try calling DataGridView.CancelEdit() after your dialog closes to end the edit session on the clicked row. This will restore the "new row" row to the grid. It disappears when you begin editing another row, which, depending on the EditMode setting may begin when you click on (enter) another row.

Resources