In C# Winforms DataGridView I am binding a List of class using the datagriview's datasource property. Is there a way to bind one of the class property to the datagriview's rowheader?
I didn't want to iterate all the rows and add row header values one by one because I will have thousands of records so I wanted the rowheader to get the values from the binded class when I set the datasource.
For example I have this class and I want the rowheaders to show the Customer ID.
private class Customer
{
public string CustomerID { get; set; }
public string CustomerFirstName { get; set; }
}
I'm afraid you have to implement datagridview's OnPaint-Method, where you paint the customer id in a loop. Once, I wanted to numerate my entries and I didn't find any other solution.
Related
I have a class that has one of its properties being of type ObservableCollection<string>
public class SizeList
{
public string ID { get; set; }
public string Name { get; set; }
//public ObservableCollection<string> List { get; set; }
public ListEntryCollection List { get; set; }
}
During a unit test I return a list of SizeList and then show it in a DataGridView to check the results I am expecting, the data is fine but I am missing the field List in the DGV; only the ID and Name are shown, so I have made a wrapper class for the ObservableCollection<string> and overriden its .ToString() method:
namespace System.Collections.ObjectModel
{
using System.Collections.Generic;
public class ListEntryCollection : ObservableCollection<string>
{
public ListEntryCollection(IEnumerable<string> collection)
: base(collection)
{
}
public override string ToString()
{
return Count.ToString() + ((Count > 1) ? " Entries": " Entry");
}
}
}
But I am still not getting the List field in the DGV, so what am I doing wrong ?
Per Column Types in the Windows Forms DataGridView Control, the only property types for which bound columns are automatically generated are numbers, text, booleans, and images.
To display other types, you need to add the column manually to the DataGridView, or use a custom column type (and even then, you'll probably have to add it manually.)
A couple of options present themselves:
You could try adding a read-only property to SizeList to display the description of the list, and see if that will result in a column being automatically created.
You can try adding a column manually, which I believe you can do in the Form Designer if you click on the DataGridView. You will probably have to override a method or two, or use an event handler, in order to change the display from the default. (It's possible, though, that it will use the ToString override you created, in which case the problem is solved.)
Or, you could create a ListSummaryDataGridViewColumn class, that can represent a list by display a count of the items in it, and add one of those manually.
We have an observable collection that consists of a custom class called Row which is used as itemsource in our Datagrid. The Row class itself consists of 3 different cell types.
public class Row
{
public TimeCell TimeCell { get; set; }
public PositionsCell PositionsCell { get; set; }
public TemperatureCell TempCell { get; set; }
}
These cell types all have the parent class Cell which contains the majority of properties. Our Datagrid consists of template columns representing each of the cells in Row with relevant bindings.
The problem is that when we do Datagrid Selecteditem we currently get a Model.Row returned whereas we would like to get the cell directly (Model.Row.TimeCell) for example if a cell in that column was clicked/selected. How can we achieve this?
You Need to cast DataGrid.SelectedItem To your custom class item i.e.
Row selRow = mainDataGrid.SelectedItem as Row;
Now you can able to access properties of Row i.e.
TimeCell timeCell = selRow.TimeCell;
Hope this will work
Thanks for letting us help you
I have a DataGridView which is data-bound to a BindingList. My DataGridView also has a couple of custom columns that I have added. These are not data-bound, but rather are generated based on items in my BindingList
(ie: an item in my BindingList of type A has a property of type B; my custom column shows B.Name
In this case, "Name" is a property of class B, and thus the property represented by the column is not directly found in the items in the BindingList).
Can anyone help me for this?
I wanted to make it generic.
e.g.
public class Fruits
{
public String Id {get;set}
public String Name {get;set}
}
public class People
{
public String ID {get;set}
public String Name {get;set}
public Fruits FavouriteFruit{get;set}
}
In BindingList as we can do sorting using custom sortable list for the properties on People, in the DatagridView but, I also wanted to sort People based on the FavouriteFruit.
You can inherit DataGRidView and add the required properties.
I am new to WPF and XAML. Sorry if this seems simple, but I have a set of classes:
Public class Master()
{
public int Id {get;set;}
public List<Student> Students { get; set; }
}
Public class Student()
{
public int Id {get;set;}
public string Name { get; set; }
}
I wish to display them in a datagrid, so I have created and configured a datagrid control on my page.
I have then bound my classes above using:
dataGrid.ItemsSource = result.Master.ToList();
This provides me with the list, but what I am trying to do is also display the student collection against each master row. At the moment all I get is (Collection) populated in the student record of the datagrid.
To move from comments to an answer:
I assume you know how to make another datagrid, since you already have 1 with correct bindings. Just copy paste another one and move it to one side.
For this other datagrid, let's call it dataGrid2.
On the first datagrid: add this to your xaml:
SelectionChanged="DataGrid_SelectionChanged"
and in code behind:
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selected = dataGrid.SelectedItem as Master;
dataGrid2.ItemsSource = selected.Students.ToList();
}
I haven't included everything, such as error checking and empty selection handling, etc. So you will need to implement it.
I have a class called EventBox that extends TableLayoutPanel. It's a table with one single row and dynamically adjusting number of columns.
During its lifecycle, this EventBox adds/removes items from itself (buttons, combo boxes etc).
What I want is to create a ListView (or something similar) that would contain multiple EventBox objects and visually display them in a list.
I've created a class called TestEventList, but I do not know what to extend!
I've tried TableLayoutPanel (I believe it's overkill), ListBox (wrong!) and now ListView.
However, ListView's Items property has a method Add which only accepts ListViewItem objects as parameters.
How can I describe my EventBox as a ListViewItem?
Or better yet, what other choices do I have?
EDIT: I obviously want the list to be able to keep track of its items: add, remove at index etc.
Firstly, ListView will not do anything on its own. You need to set ListView.View to an instance of GridView.
I recently had to solve the dynamic column problem. The solution I chose is bindable and MVVM compatible, just in case you want to use that pattern (i was). I created a behavior (to avoid extending GridView) that will dynamically inject and remove columns as a source structure updates. This behavior needs dependency property that you bind to a instance of a class that defines the columns. The column class should allow you to define columns where a column is the property you are binding to on the source data, and a key (to represent the cell type).
public class ColumnDefinition
{
public string Key{ get; set}
public string ContentBindingPath { get; set;}
}
When the columns structure changes, the behavior builds and injects (or removes) columns into the attached GridView. The behavior builds each column based upon a series of key/value pairs defined on the behavior. This is to allow the XAML to specify the cell template to apply to the new columns, enforcing seperation of concerns.
public class CellTemplateDefinition
{
public string Key { get; set; }
public DataTemplate ColumnTemplate { get; set;}
}
public class DynamicColumnBehavior: Behavior<GridView>
{
public IEnumerable<ColumnDefinition> Columns
{
get { return (IEnumerable<ColumnDefinition>)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
// Using a DependencyProperty as the backing store for Columns. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", typeof(IEnumerable<ColumnDefinition>), typeof(DynamicColumnBehavior), new UIPropertyMetadata(null));
public static void OnColumnsChanged(DependencyObject sender, DependencyPropertyChangedEventArgsargs)
{
DynamicColumnBehavior behavior = sender as DynamicColumnBehavior;
if(behavior != null) behavior.UpdateColumns();
}
public IEnumerable<CellTemplateDefinition> Cells { get; set; }
private void UpdateColumns(){ throw new NotImplementedException("I left this bit for you to do ;)");}
}