Show row numbers in GridControl PrintPreview - c#

I have problem with DevExpress GridControl PrintPreview. How can I create column with row numbers in PrintPreview? I need to show ordinal number for each row PrintPreview.
Thanks for help.

I think the easiest way to do this from a direct export is to add an unbound data column:
Go into the grid designer and add a column; name it (colRowNumber or whatever)
Move the column to be the first column in the layout
In the column's properties:
a. set UnboundType to Integer
b. set OptionsColumn.AllowEdit set it to False
Within the grid, create an event for CustomUnboundColumnData
Your code for the CustomUnboundColumnData event should look something like this:
private void gridView1_CustomUnboundColumnData(object sender,
DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs e)
{
if (e.Column == colRowNumber)
e.Value = e.ListSourceRowIndex + 1;
}
From here, now matter how your grid is ordered or filtered, the "Row Number" column will always contain the 1-based row number of the displayed data.

Related

C# Convert DatagridViewTextbox to DataGridViewComboBoxCell

I have a DataGridView table that is already filled.
Now, when I click on a cell in the DataGridView, I want to make a ComboBox out of the cell, where I can then choose a selection of "Items".
Dgv_Data_List is my DataGridView.
private void Dgv_Data_List_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
DataGridViewComboBoxCell CboCell = new DataGridViewComboBoxCell();
CboCell.Items.AddRange("Yes", "No");
Dgv_Data_List.Rows[e.RowIndex].Cells[e.ColumnIndex] = CboCell; <--At this point my program crashes
}
I don't want any fixed comboboxes. They should be created at runtime as soon as they are needed.
It is unclear how the grid is filled with data. You may get away with this if the columns and rows are manually added, however if the grid has a DataSource, then when you “double-click” into a cell and set the cell as a combo box as you show… then the “current” cells value better be a “Yes” or “No” or you will get the grids DataError complaining about the value in the cell not being a valid combo box value.
I would think you would have to “delete” the current cells value just to avoid the possible error. Something like…
DataGridViewComboBoxCell CboCell = new DataGridViewComboBoxCell();
CboCell.Items.AddRange("Yes", "No");
Dgv_Data_List.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "";
Dgv_Data_List.Rows[e.RowIndex].Cells[e.ColumnIndex] = CboCell;
Setting the cells value to a blank string will work. HOWEVER, if the column type of the cells underlying data source is of a numeric type… then you will get the grids DataError complaining that the “Yes” or “No” value is not a valid numeric value… so technically this will ONLY work if the column type is a string type column. As most of this is unknown, I can only assume ALL the cells are of a string type.
As the code given, you created comboboxcell but not convert the grid view. so do this instead.
this.dataGridView1[CboCell] = new DataGridViewComboBoxCell();
Try this in the place of creating the comboboxcell.

Datagridview: Get column name by right clicking on column header (read info)

I have two datagridviews, and they both share the same datasource. I have chosen to only show the first n columns on my first dgv, and the rest n columns of my datasource on the second dgv like this:
for (int i = 0; i < mytable.Columns.Count; i++)
{
dataGridView1.Columns[i].Visible = i < n;
dataGridView2.Columns[i].Visible = i >= n;
}
Introduction: I want to right click and move columns from one datagridview to another at will. I do this by making the respective columns visible and not visible, since both datagridviews share the same datasource. I have run into problems concerning column indices of course.
Consider this example: I have a datatable of 5 columns, and I give that datasource to both my datagridviews. I decide to make the first 3 columns of the datatable visible on the first datagridvew, and the two remaining columns visible on the second. Now, if I wanted to move a column from the second datagridview to the first, I would first fire this event:
private void dataGridView2_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
var ht = dataGridView1.HitTest(e.X, e.Y);
currentColumnIndex = ht.ColumnIndex;
if ((ht.Type == DataGridViewHitTestType.ColumnHeader))
{
contextMenuStrip2.Show(MousePosition);
}
}
}
I have made it so that this will only show the context menu if the user has right clicked on a column header. Then, throught the contextmenu this happens:
private void moveToFirstGridToolStripMenuItem_Click(object sender, EventArgs e)
{
dataGridView2.Columns[currentColumnIndex+dataGridView1.Columns.GetColumnCount(DataGridViewElementStates.Visible)].Visible = false;
dataGridView1.Columns[currentColumnIndex + dataGridView1.Columns.GetColumnCount(DataGridViewElementStates.Visible)].Visible = true;
currentColumnIndex = -5;
}
currentColumnIndex is a global variable which was to track the index of the column the user right clicked on.
Problem: The problem is that this currentColumnIndex gets the index of the current datagridview's index, and not the whole dataset. In my example, if I go to the second dgv and right click the header of the second column, currentColumnIndex shows 1 instead of 4, which would be the correct global index. This leads to problems later on, when you for example move the second column first, and then the first one.
I believe it is important to have a way to know the correct global index of my columns. I wasn't sure whether this can be achieved, so I thought that maybe I could look for column names, since all the column names of my dataset will be unique. The question then is how to get the header column text when you right click on it, given the structure I have.
The question could have been much shorter, just including the last sentence of the last paragraph, but I wanted to give more accurate view of what is going on.
Answering my question: This will just solve the problem I described I had currently. It doesn't actually answer the question at the top. which is how to find the column name by right clicking. However it shouldn't be a problem getting the name and column info that you need when you actually have the correct index: dataGridView1.Columns[i]...
Solution of my problem:
It seems I don't need to look for a way of detecting the column names. Instead of using the DataGridViewi_MouseDown events, I now use the dataGridViewi_ColumnHeaderMouseClick which uses the DataGridViewCellMouseEventArgs class. So I moved the code from the former event to the latter. Now, whenever you use e.ColumnIndex, you actually get the correct index, meaning the index of the whole datatable and not just the current datagridview's index.
To make this work I also change the code for making columns visible. Now it's just:
private void moveToFirstGridToolStripMenuItem_Click(object sender, EventArgs e)
{
dataGridView2.Columns[currentColumnIndex].Visible = false;
dataGridView1.Columns[currentColumnIndex].Visible = true;
currentColumnIndex = -5;
}
Find column name/header via right click:
Private Sub dgv1_ColumnHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles dgv1.ColumnHeaderMouseClick
If e.Button = Windows.Forms.MouseButtons.Right Then
MsgBox(e.ColumnIndex & " " & dgv1.Columns(e.ColumnIndex).Name & " " & dgv1.Columns(e.ColumnIndex).HeaderText)
End If
End Sub

Datagrid View cells as Boolean values: Using Datagrid view similar to MS Outlook Meeting Schedular

I am trying to develop a time sheet similar to Outlook meeting scheduling thing(Picture attached from internet). I have days as rows and time as columns. I am trying to use cells in Datagrid view such that when user select cell corresponding to day and time i get input by this selection (nothing to be displayed in cells, I just want to use selected cell as my input). I have declared columns as Boolean type so that selected cell corresponds to True and un-selected as False.
foreach (DataGridViewColumn column in this.dataGridView1.Columns)
{
column.ValueType = typeof(Boolean);
}
However I am not sure how to proceed with this, as I have just declared and not initialized Boolean cells. I am looking a way to initialize cells such that no text appears in cells [blank cells which will be highlighted on selection] and I can just take input based upon selection/non selection of cells.
Since you want the selected cells as input you can use DataGridView.SelectedCells (docs here). From the returned collection you can get the row and column of each selected cell, which in your case maps to day and time.
Here's an example:
private void button1_Click(object sender, EventArgs e)
{
DataGridViewSelectedCellCollection cells = this.dataGridView1.SelectedCells;
foreach (DataGridViewTextBoxCell cell in cells)
{
Console.WriteLine("Selected cell: column: {0} row: {1}", cell.ColumnIndex, cell.RowIndex);
}
}
Output when I selected a couple cells in the third column:
Selected cell: column: 2 row: 2
Selected cell: column: 2 row: 1

winform multiple select grid row and get row index of selected rows

I have a databound gridview in my winform. I want to know how to get the index of Currently selected rows i.e multiple rows.
I am able to do this with a single row. but is there a way I can have a checkbox or something in which I can index of multiple rows.
The Image below will help u understand better of my requirement.
First set CellContentClick event to your DataGridView.
dataGridView.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.onCellContentClick);
For every cell click it will invoke the following method. Here you can create a list and populate it with clicked row index.
public void onCellContentClick(DataGridViewCellEventArgs cell)
{
// Check whether selected cell is check box column, here 0 indicates the check box column.
if (cell.ColumnIndex == 0)
{
bool isChecked = (Boolean) dataGridView[cell.ColumnIndex, cell.RowIndex].EditedFormattedValue;
if(isChecked)
{
// Below will give you the selected cell row index, for multiple rows you can populate those index in list or whatever you convenient with.
cell.RowIndex;
}
}
}
Use DataGridView.SelectedRows property to get all selected rows.
To select multiple rows:
DataGridView.MultiSelect = true;

How do I select a value in a DataGridViewComboBoxCell?

I have DataGridViewComboBoxCell and a DataTable. The data in Table I bound with DataGridViewComboBoxCell using DataSource and set ValueMember, and DisplayMember.
private void Form1_Load(object sender, EventArgs e)
{
DataGridViewComboBoxCell comboBoxCell = new DataGridViewComboBoxCell();
dataGridView1.Rows[0].Cells[0] = comboBoxCell;
comboBoxCell.DataSource = dataTable;
comboBoxCell.ValueMember = "ID";
comboBoxCell.DisplayMember = "Item";
}
How can I programmatically set the value in the cell when the form loads?
In the simple ComboBox I know a property SelectedIndex.
I tried comboBoxCell.Value = ...; but it gives an exception.
And tried
private void dataGridView1_CellFormatting(object sender,
DataGridViewCellFormattingEventArgs e)
{
e.Value = 1;
}
It sets a new value in the cell, but I need to select a value.
Form loaded and I have empty cell.
And some data in the ComboBox.
When I put this code dataGridView1.Rows[0].Cells["ComboColumn"].Value = "1"; right after comboBoxCell.DisplayMember = ... (see above), it works fine.
The value "1" in the ID column corresponds to the value "Second" in the Items column.So, I get the correct result.
Sorry for my English and my newbie code :)
Instead of adding a cell to your grid add a DataGridViewComboBox column.
DataGridViewComboBoxColumn c = new DataGridViewComboBoxColumn();
c.Name = "ComboColumn";
c.DataSource = dataTable;
c.ValueMember = "ID";
c.DisplayMember = "Item";
dataGridView1.Columns.Add(c);
To select a particular value you set the Value property of a given cell.
dataGridView1.Rows[rowIndexYouWant].Cells["ComboColumn"].Value = 1;
Note that the type here is important! In comments you say you get a System.FormatException. This can be caused by setting the wrong type to the value.
When you set the value to 1 you are assigning an int - if for some reason you have strings in the ID column you will get the System.FormatException exception you are seeing.
If the types differ you need to either update the DataTable definition or set the value to a string:
dataGridView1.Rows[rowIndexYouWant].Cells["ComboColumn"].Value = "1";
Also note that this value must be present in the ID column of the DataTable that you have set as the source of the grid.
It is usually easiest to work with a DataGridView when it has its DataSource set. In this case you can bind the ComboBoxColumn to the grid's DataSource using the DataPropertyName property.
c.DataPropertyName = "GridDataSourceColumnName";
This allows the columns value to be taken from the grid data source and for changes to the column to directly change that data source.
Lastly, do not use the CellFormatting event here - this event is not intended for this sort of use. It is usually best to do this sort of work in the DataBindingComplete event (if you only want it done once) or during some event like DefaultValues needed or RowValidating.
By using CellFormatting you will probably make it impossible for users to manually edit the combo box.

Categories