I have a WinForm DataGridView bound to a List<> of objects and I would like to set the datasource of the DataGridView to display only so many records at a time. From a few searches it looks like there is a way to do this however I have not found the exact method. Is there a way to set the total row count and then set an event that fires when more rows are needed? I am thinking that I need to do something like:
private const int AMOUNT = 1000;
private int pageCount = 0;
this.grdItems.VirtualMode = true;
// Initial Load
this.grdItems.RowCount = myList.Count();
this.grdItems.DataSource = myList.Take(AMOUNT);
// When the user scrolls to the bottom of the list
this.grdItems.DataSource = myList.Skip(pageCount++).Take(AMOUNT);
You need to set VirtualMode =true to get it working
Related
I have an application with multiple datagridviews in a tabcontrol.
One of the tabcontrols has 4 columns that are filled by the datasource.
I don't use autogenerate columns, but use the DataPropertyName to bind values to the columns.
I also have 2 columns i create, wich are filled manually, after assigning the DataSource.
Values in this datagridview are filtered values from a datagridview somewhere else in the application.
When i filter, then go to the tab containing the datagridview, the manual columns are empty.
Changing the filter (but not the results) fills those colums.
How can i get the columns that are manually filled to always show their values?
Calling Refresh() or Update() on the datagridview doesn't solve my problem
Short version of my code:
I actually use a class that inherits from DataGridView
//fill datagridview
PcbLink[] links = Service.Instance.Client.queryPcbLinks();
List<Pcb> pcbs = new List<Pcb>();
foreach (PcbLink link in links)
{
PcbFilter pcbfilter = new PcbFilter();
pcbfilter.pcb_id = link.pcb_id;
Pcb[] res = Service.Instance.Client.queryPcbs(pcbfilter);
pcbs.Add(res[0]);//only first element because pcb_id should always be unique -> only one row
}
cdgvUsage.SetData(pcbs);//setData is used as cdgvUsage.DataSource = pcbs, but does some stuff internally
for (int i = 0; i < links.Length; i++)
{
SortableBindingList<Pcb> dataSource = cdgvUsage.GetData<Pcb>();
cdgvUsage["count", i].Value = links[i].count;
char variantchar = (char)('a' + (char)(dataSource[0].variant));
cdgvUsage.Columns["variant"].ValueType = typeof(string);
cdgvUsage["variant", i].Value = variantchar.ToString();
}
I believe after asigning DataSource to the dataGridView changes must be saved in datasource also otherwise they will not be reflected in the dataGridView (as it takes data from datasource everytime you do Refresh() or Update()).
Make sure manually filled values are stored in dataSource.
I'am using a grid control from devexpress in a desktop application(C#).
I set a datasource and then I export to Excel.I want that all my columns take the width of longest row value from that column.
In this grid I use different datasources .
In load form I set :
gvExport.OptionsPrint.AutoWidth = false;
gvExport.BestFitColumns();
grdExport.DataSource = ds;
XlsExportOptions vOptions = new XlsExportOptions();
vOptions.TextExportMode = TextExportMode.Text;
vOptions.ShowGridLines = true;
vOptions.SheetName = "Test";
prmFileName = "Test.xls";
grdExport.ExportToXls(prmFileName, vOptions);
My ds can be a list or a dataTable.
1.Can somebody hepl me to autosize the lenght of columns?
2.How can I set to ladscape the Excel page that I generated?
Thanks
For the first part of the question you can use
GridView.OptionsView.ColumnAutoWidth = true
if you want to set the width according to a particular column, let say the first column you have to inheret the GridView and then override the functions BestFitColumn and OnColumnWidthChanged.
For the second part you have to use the printing system like this:
PrintableComponentLink link = new PrintableComponentLink(new PrintingSystem());
link.PaperKind = System.Drawing.Printing.PaperKind.A4;
link.Component = myGridControl;
link.Landscape = true;
and then use an ExportOption, here an example of Xls:
XlsExportOptions _Options1 = new XlsExportOptions();
_Options1.SheetName = fileName;
_Options1.ExportMode = XlsExportMode.SingleFile;
link.ExportToXls(sfd.FileName, _Options1);
Note for others there is XlsxExportOptions, PdfExportOptions,RtfExportOptions ...etc
Tou should know that the BestFitColumns() method iterates on the rows of the data source to compute the best width for the columns.
So, you have to put it AFTER setting your data source.
Therefore, I recommend you not to use this method and set manually the width of the columns instead. In fact, the BestFitColumns() method slows considerably the loading of your grid (if you are dealing with >1k rows).
For Exporting to a landscape mode, you'd probably find an answer here.
I am using linq2sql to add a record to my datagridview and refreshing the grid. Right now after refresh it moves the row selection to the top. How would I tell it to highlight the most recent added record?
Not sure if this would help but I have included the code below I am using to find out the pk of the selected row. As what I would like to do is kind of the opposite. Thanks
//get selected row index
int index = this.dataGridView1.CurrentRow.Index;
//get pk of selected row using index
string cellValue = dataGridView1["pkColumn", index].Value.ToString();
//change pk string to int
int pKey = Int32.Parse(cellValue);
If you know in advance that anytime a new item is added, it should appear at the bottom of the list, you could use:
int index = this.dataGridView1.Rows.Count - 1;
this.dataGridView1.Rows[index].Selected = true;
this.dataGridView1.FirstDisplayedScrollingRowIndex = index;
But, if your order the list by other column then you're not going to get the desired results.
I recommend you, is to search for the row-index you need to give the selection to, this could be performed by a function, let's say int SearchRowIndexForPKValue(int pKey), that will perform a look-up within the cell values of the column that contains your PK/ID ("pkColumn") returning the row index. In such way the code above should looks like:
int index = SearchRowIndexForPKValue(pKey);
this.dataGridView1.Rows[index].Selected = true;
this.dataGridView1.FirstDisplayedScrollingRowIndex = index;
EDIT: int SearchRowIndexForPKValue(int pKey) is not an existing built-in method of the DataGridView. You must declare it and implement it in your code; for the body of the method, you can get the code from this post.
I Have two tables I select a record from table 1 to show information in table 2 on double click in one of information I got window to update data after closing this window I have to refresh the two tables and I want the same row be selected in table 1.
I was working in wpf and I use selectedindex.
Now I use this for the moment:
int index = dgTable1.Grid.CurrentRow.Index;
///**
frm.ShowDialog();
frm.Dispose();
ReloadTable1();
selectedindex(index)
with
private void selectindex(int index)
{
dgwTable1.Grid.Rows[index].Selected = true;
DATAtype data= dgwTable1.GetObjectFromRow<DATAtype>(index);
LoadTable2(data);
}
It work But I have Grid_SelectionChanged for table1 and don't fire i have to reload data, also If the scroll bar is down when I use this I return to the top of table 1!
But I know this not the right way to do it:( and it's too simple in wpf :/
dgTable is a UserControl with a DataGridView as a Grid
To Save Current Index :
int index = dataGridView1.CurrentRow.Index;
After Editing:
dataGridView1.Rows[index].Selected = true;
Hope this helps.
May be DataView and BindingSource with filters better to use?
DataView view = new DataView(_table);
BindingSource tSource = new BindingSource();
tSource.DataSource = view;
_dataGridView.DataSource = _tSource;
_tSource.Filter = "Value=0";
like this...
To save scrolling use myDataGridView.FirstDisplayedScrollingRowIndex
int scrollIndex = 0;
if (myDataGridView.FirstDisplayedScrollingRowIndex >= 0)
scrollIndex = myDataGridView.FirstDisplayedScrollingRowIndex;
after editing:
if (myDataGridView.Rows.Count > 0)
myDataGridView.FirstDisplayedScrollingRowIndex = scrollIndex;
Hope this helps.
In my opinion, the easiest way to solve your problems, is to use the MVVM pattern. In your ViewModel for your View that contains the two DataGrids, you have a property like "SelectedNameOfContentClass" that is bound to first DataGrids SelectedValue-property. This "SelectedNameOfContentClass"-property is also bound to seconds datagrid DataSource. So if you changes the selected row in first DataGrid, the Source of second DataGrid automatically updates.
The list, that is bound to first Datagrids DataSource, should be an ObservableCollection. For the dialog you can use the IEditableObject interface in your objects.
I have a winforms datagridview that seems to always have at least one row selected all the time. I'm not interested in being able to select the rows at all really, I just need the user to be able to select the checkbox in column 1.
Any ideas why there is always at least 1 row selected?
How can i prevent this?
Will it affect the ability to select the checkbox in column1?
Below are my Datagridview settings:
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
this.dataGridView1.DefaultCellStyle.ForeColor = Color.Black;
this.dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
this.dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
this.dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
this.dataGridView1.MultiSelect = false;
this.dataGridView1.RowHeadersVisible = false;
this.dataGridView1.RowsDefaultCellStyle.BackColor = Color.WhiteSmoke;
this.dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.LightGray;
this.dataGridView1.ColumnCount = 0;
colSelect = new DataGridViewCheckBoxColumn();
colSelect.HeaderText = "Select Message";
colSelect.Width = 90;
this.dataGridView1.Columns.Insert(0, colSelect);
this.dataGridView1.Columns[0].DataPropertyName = "msgSelect";
Goober, I encountered a similar problem, where I needed user to select rows using checkboxes. The first row is always selected by default after the gridview is populated irrespective of the gridview settings. To make sure the first row is not selected, everytime the gridview is populated, do a ClearSelection():
this.dgridvw.DataSource = this.MyTable;
this.dgridvw.ClearSelection();
ClearSelection() clears all the selected rows.
You should use DataGridView.ClearSelection() to remove any selection(s) after you have populated your DataGridView.
Also you can make specific columns read only allow which would allow to restrict editing to your checkbox column only. See DataGridViewColumn.ReadOnly Property
Make sure your are NOT calling the method to load the data from the form constructor. If you call it from the form.load()
also after the datagridview is loaded do this
DataGridView.Rows[0].Selected = false;
Select the datagridview. Then, in the properties window scroll down until you find the property SelectionMode and change it to FullColumnSelect.
Alternatively if you want them to just select one checkbox at a time change it to CellSelect