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.
Related
I'm using MySQL .net connector to fill a Datagridview using Mysqladapter and Datagridview.Bindingsource. That works good, but I want to change one thing:
In the table which is filled to the DataGridview, there is a column with a text type. The cells in this columns are displayed as a Datagridviewtextboxcell in the datagridview, but I want to change it to DataGridviewComboboxCell (the users should select between ~10 items).
I already tried a lot but nothing worked as it should. The Columns in the DataGridview are readonly, I cannot change DefaultCellTemplate to a DataGridviewComboboxCell, cause it doesn't inherit DataGridviewTextboxcell.
I also tried this: Gridview - convert textboxcell to comboboxcell and back and I think my problem could be solved over this way, but with this solution I have also 1 problem: It doesnt show a DropDown Button.
Any help will be greatly appreciated.
To do this you need to add a new DataGridViewComboBoxColumn to the grid and then hide the text box column.
I show this using code below but you can do the same using the designer (just set the properties I set in code using the designer).
The key things to note are:
DataPropertyName refers to a property of the grid's data source - likely your text box source
You need to provide the column with its own data source
DisplayMember and ValueMember refer to the data source of the column
Here is the code to add the column:
// Here I do this in the form constructor - there are other places you can do it
public Form1()
{
InitializeComponent();
DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
// You need to set some properties on the column to make it work
// Datasource is the source (usually a list) of objects to show in the combobox
col.DataSource = dataSource;
col.DataPropertyName = "ColumnInGridDataSource";
col.DisplayMember = "DisplayProperty";
col.ValueMember = "ValueProperty";
dataGridView1.Columns.Add(col);
// This hides the textboxcolumn
dataGridView1.Columns["YourTextBoxColumnName"].Visible = false;
}
In the answer you linked, before the line:
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] = cb;
Try adding:
cb.DisplayStyle = DataGridViewComboBoxDisplayStyle.CHOOSE_ONE;
cb.FlatStyle = FlatStyle.CHOOSE_ONE;
I am not sure how exactly you want to style your comboboxes, so instead of "CHOOSE_ONE", try out the styles and pick the style you want.
Edit: Seems like you're not changing it to a combobox at all. Try this:
var values = new List<string> { "a", "b", "c" };
var cell = new DataGridViewComboBoxCell();
cell.DataSource = values;
dataGridView1[col, row] = cell;
I have an existing application with a new requirement to show an image in a DataGridView cell to denote whether the record has a specific flag associated with it or not (not user editable, this comes from the DB).
If there is a flag, I show the corresponding image, and if there's no flag, I want nothing to be shown in the column.
The DataGridView columns weren't created in Visual Studio designer, or else this would easy. I could just set the NullValue property on the column. Instead the columns are created at runtime when all the data is loaded into a DataTable, and then a DataView is created from that DataTable, and then the DataGridView's Datasource is set to the DataView.
I can't completely rewrite this, or else I'd just define the columns in VS Designer instead of this ridiculous way of just letting the columns be defined from the DataTable.
My question is then, how can I make it so the column with the Images shows nothing when the underlying data table has a null?
Here's some pseudo C# to demonstrate what I mean. Remember, I didn't write it to use two DataTables like this; it was that way when I had it handed to me, and I don't want to make drastic changes just to add a new column...
DataTable rawData = someMethodThatReturnsMyRawData();
DataTable data = new DataTable();
data.Columns.Add("Flags", typeof(Image));
data.Columns.Add("SomeOtherColumn");
foreach (DataRow rawDataRow in rawData.Rows)
{
DataRow dataRow = data.NewRow();
bool hasFlagType1 = false;
bool hasFlagType2 = false;
if (rawDataRow["FlagType1ID"] != DBNull.Value)
{
hasFlagType1 = true;
}
if (rawDataRow["FlagType2ID"] != DBNull.Value)
{
hasFlagType2 = true;
}
if (hasFlagType1 && hasFlagType2)
{
dataRow[0] = Properties.Resources.BothFlagsImage;
}
else if (hasFlagType1)
{
dataRow[0] = Properties.Resources.FlagType1Image;
}
else if (hasFlagType2)
{
dataRow[0] = Properties.Resources.FlagType2Image;
}
else
{
//If neither flag set, I don't want it to show anything,
//but if I leave it as null, a little box with an X in it shows up
//I could set it to some transparent GIF here, but that seems lame
}
dataRow[1] = rawDataRow["SomeOtherColumn"];
data.Rows.Add(dataRow);
}
DataView dv = new DataView(data, string.Empty, "SomeOtherColumn ASC", DataViewRowState.CurrentRows);
this.emptyDataGridViewFromDesigner.DataSource = dv;
// How can I modify the column "Flags" at this point to show nothing if the value is null?
EDIT: Here's a screenshot so you can see what I mean by the little box with an X - those are all nulls...
Also, it has to be .NET 3.5, so if there's a solution in .NET 4.0 only, I'm out of luck.
I figured this out...
Have to cast the column as a DataGridViewImageColumn, then set the DefaultCellStyle.NullValue for that column to null. From my example above, you'd do it like this...
((DataGridViewImageColumn)this.emptyDataGridViewFromDesigner.Columns["Flags"]).DefaultCellStyle.NullValue = null;
I guess I jumped the gun asking here, but hope this helps someone else sometime.
It's FAR easier to simply assign new Bitmap(1,1); to the cell's .Value property and move on. My app was throwing exceptions whenever I tried to assign NULL to the Cell's Value, even with the modified DefaultCellStyle.NullValue
Something like this works as intended, every time, without any hassles or arcane/obscure settings:
dataGridView1.Rows[index].Cells["CellName"].Value = isFlag ? Properties.Resources.FlagImage : new Bitmap(1,1);
To fix whole grid, just add this code to Form constructor. (and change name of your dataGrid):
Load += delegate
{
// remove default [x] image for data DataGridViewImageColumn columns
foreach (var column in dataGridView1.Columns)
{
if (column is DataGridViewImageColumn)
(column as DataGridViewImageColumn).DefaultCellStyle.NullValue = null;
}
};
I have a DataGridView bound to an ObjectDataSource some of the columns are hidden including the ID column. The problem is that the ID column shows up even when its visible property is set to false. Has anyone run into this problem before? Setting the width to zero is not an option since the grid doesn't allow columns with a width less than 5 pixels wide so it still shows the column on the grid no matter what.
The strange thing is that the ID column wasn't always showing. After I worked on the app for a bit the columns appeared again.
DataGridView is not set to auto generate columns. I am building to version 4.0 of .NET and C#.
Here is the code in the form constructor.
dgvActiveMiners.AutoGenerateColumns = false;
dgvAvilableMiners.AutoGenerateColumns = false;
dgvOperationResults.AutoGenerateColumns = false;
dgvActiveMiners.Columns["dgvActiveMinersRecordId"].Visible = false;
dgvAvilableMiners.Columns["dgvAvilableMinersRecordId"].Visible = false;
dgvOperationResults.Columns["dgvOperationResultRecordId"].Visible = false;
This is the generated code for the grids.
this.dgvOperationResults.AllowUserToAddRows = false;
this.dgvOperationResults.AllowUserToDeleteRows = false;
this.dgvOperationResults.AutoGenerateColumns = false;
this.dgvOperationResults.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgvOperationResults.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.dgvOperationResultRecordId,
this.nameDataGridViewTextBoxColumn2,
this.typeIdDataGridViewTextBoxColumn,
this.amountDataGridViewTextBoxColumn,
this.operationIdDataGridViewTextBoxColumn});
this.dgvOperationResults.DataSource = this.operationResultBindingSource;
this.dgvOperationResults.Location = new System.Drawing.Point(12, 40);
this.dgvOperationResults.MultiSelect = false;
this.dgvOperationResults.Name = "dgvOperationResults";
this.dgvOperationResults.ReadOnly = true;
this.dgvOperationResults.Size = new System.Drawing.Size(498, 247);
this.dgvOperationResults.TabIndex = 16;
I don't know what else I could be missing?
Thanks!
Suggestion 1:
Try explicitly setting the DGV Column's Visible property to false in the FormLoad event:
dataGridView.Columns["YourIdColumn"].Visible = false;
Suggestion 2:
Try changing your column dgvActiveMinersRecordId from the first column in the DGV to the last column.
To try and answer this a bit more generically for the next person who comes along, like me...
This does seem to be a bug, but the work around is to:
Make sure the columns you want to hide are displayed last
This will depend on your code, but for some this will be:
SQL code changed to return the columns later
Change the code that adds the datagridview columns putting the "to hide" columns at the end
Setting the Columns[x].DisplayIndex such that the columns appear last, as per #Steve's post
I have the same issue.
The following line, still leaves the column visible, even though exploring the value shows it false.
dataSelected.Columns["id"].Visible = false;
I didn't have this issue, until I had set the DisplayIndex on a column
dataSelected.Columns["ipagenum"].DisplayIndex = 6;
Moving the offending columns DisplayIndex to the end, corrected this issue.
dataSelected.Columns["id"].DisplayIndex = 15;
Maybe a bit late but I was beating myself up with the same problem, I had two separate forms with DataGridViews both bound to different DataTables. One had no problem hiding the 1st column, on the other everything I tried didn't work, until...
Note: ["newCol"] is the first (i.e. column 0) column in the data table.
This code Fails to hide column [0] (or by name ["NewRow"])
...
MyDataGridView.DataSource = MyDatatable;
MyDataGridView.Columns["NewRow"].Visible = false; // doesn't hide (col 0)
// MyDataGridView.Columns[0].Visible = false; <<<< this didn't work either
MyDataGridView.Columns["Changed"].Visible = false;
MyDataGridView.Columns["Active"].Visible = false;
MyDatatable.RowFilter = "[Active] = 1";
...
this code works:
...
MyDataGridView.DataSource = MyDatatable;
MyDatatable.RowFilter = "[Active] = 1";
MyDataGridView.Columns["NewRow"].Visible = false; // YAY!! Now it hides
// MyDataGridView.Columns[0].Visible = false; <<<< and this works too
MyDataGridView.Columns["Changed"].Visible = false;
MyDataGridView.Columns["Active"].Visible = false;
...
Spot the difference? It's Where I specify the RowFilter.
The other form doesn't have a starting RowFilter but in both forms I later change the RowFilter (depending on user actions), column 0 never comes back.
Seems specifying RowFilter too soon after hiding columns fails for column 0.
Very very weird!!!! Very very frustrating!!!!
That's odd.
Are you certain you are calling the right column name? I realize that would be a stupid mistake to make, but it happens!
Here's a simple test you could try:
void test(string columnName, bool visibility) {
if (dataGridView1.Columns.Contains(columnName)) {
dataGridView1.Columns[columnName].Visible = visibility;
} else {
throw new Exception(string.Format("Column '{0}' does not exist in DataGridView '{1}'.", columnName, dataGridView1.Name));
}
}
I would like to contribute a perspective that has not been mentioned.
Each column of the DataGridView has a property name. You can directly access the column by name, as you would to access any other element. For example: ColumnName.Property = AnyProperty. In your case: ColumnName.Visible = false.
I think it is cleaner, more direct, and less likely to make a mistake. We also help a bit the compiler :)
In this way, it is not necessary to use the property name of the DataGridView, neither locate the desired column mediate a string (which potentially can be commited
an error). I mean this: YourDataGridView.Columns ["YourColumn"] Property = AnyProperty.
I had the same issue and none of the above worked for me. My fix was to set a DataPropertyName at least for the column that should be hidden in the designer at "Edit columns".
If you want to hide a column by name, you have to give a Name at your column. Initiliaze the property Name and after you can use it by code.
I was having the same problem, and I did not want have to change the index of my id column to the visible property works. So I noticed that after I indicated that the id column visible = false, I was deleting the last row of the DataGridView and this is what was making the id column appear. So I delete the row first and then indicate that the id column = false.
I have a similar problem. I added an unbound checkbox column to my data bound grid. It became the first column.
When I stepped through my grid like so:
for (int i = 0; i < grvQuoteCostSheets.RowCount; i++)
{
grvQuoteCostSheets[grcQCostSProfit.Index, i].Value
= (Convert.ToInt32(grvQuoteCostSheets[grcQCostSPrice.Index, i].Value) - Convert.ToInt32(grvQuoteCostSheets[grcQCostSTotalCost.Index, i].Value));
}
idColumn.Visible = false; //Need to rehide.
The first hidden column visibility switched to False. I moved the CKBox column from first to 3rd place as suggested in a different answer (the next two columns being an ID value & Line# respectively, and hidden) and the checkbox column stayed hidden. I was hiding the ID column after the math as it was flipping to Visible. I just lived with it before (hiding the ID column after the math loop), but now that I added the checkbox column, I decided to dig a bit, and here I am.
I also tried doing the math in a list grabbed from the grid, and the checkbox column would still flip to Visible when the CKBox was first. I’m still stuck with the first hidden column wanting to flip to visible, so I re-hide it.
I do have AutoGenerateColumns = False and am explicitly setting the first column visibility to false as well. Both to no avail.
Don't know if anybody is still struggling with the issue.
I had the same problem and was setting the visible property in the dataSourceChanged event.
When I put the visible false in the show event instead it worked.
Developing In: c# winforms without any Database Connections
Description: In my DataGridView, columns were dynamically generated.At some point some of the columns need to be DataGridViewLinkColumn property. I was tried in many ways but didn't achive this.
I hope someone from here would help me :)
Thanks In Advance.
Try this:
DataGridViewLinkColumn links = new DataGridViewLinkColumn();
links.HeaderText = "Hello";
links.UseColumnTextForLinkValue = true;
links.Text="http://microsoft.com";
links.ActiveLinkColor = Color.White;
links.LinkBehavior = LinkBehavior.SystemDefault;
links.LinkColor = Color.Blue;
links.TrackVisitedState = true;
links.VisitedLinkColor = Color.YellowGreen;
dataGridView.Columns.Add(links);
You will need to switch off AutoGenerateColumns, then generate each column yourself.
Setup the normal columns as type DataGridViewTextBoxColumn, then for the columns which need to be Linked columns set them up as type DataGridViewLinkColumn.
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