I am looking for a Windows Forms Control that looks like a grid of a check boxes in C#. Something like this I guess, hope it makes sense.
So how would I go about making this happen, is it even possible?
You can use TableLayoutPanel, this link may help you to know some of its properties, and this link is example for using it
Strongly avoid a TableLayoutPanel it is much too expensive with this many check boxes.
DataGridView is the appropriate choice, change the column types to DataGridViewCheckBoxColumn. Editing only requires a single real checkbox control, taken care of automatically. No problems with focus either.
Making your own is a very reasonable approach as well, you can make it look any way you want. Derive a class from Control, Panel if you need it to be scrollable. ControlPaint.DrawCheckBox() can be useful.
Use a TableLayoutPanel to render the check boxes.
This sample creates a TableLayoutPanel by code:
TableLayoutPanel tableLayoutPanel = new TableLayoutPanel();
int rowCount = 2;
int columnCount = 2;
for (int row = 0; row < rowCount; row++)
{
tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
for (int column = 0; column < columnCount; column++)
{
tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
CheckBox checkBox = new CheckBox();
tableLayoutPanel.Controls.Add(checkBox, column, row);
}
}
this.Controls.Add(tableLayoutPanel);
Related
I have a string that contains: "# of rows, # of columns, Row'X'Col'X'=Serial#, ...
How do I create a DataGrid table with the number of rows and columns defined, and then place the serial #s into the grid.
Examples:
2,1,R1C1=111,R2C1=112,
2,2,R1C1=211,R1C2=212,R2C1=213,R2C2=214,
thanks
Below is code that does what you are asking; however I must point out some problems with this approach. First, getting the total rows and cols from the first two elements in order to create your table is risky. If that data is wrong, this code will most likely crash or possibly omit data. Example if the input is: 2,2,RXCX=.., RXCX=.., RXCX=.., RXCX=..,RXCX=, RXCX=… This line will only get the first 4 values.
Worse… this will crash… if the input is 2,2,RXCX=.., RXCX=.. Then it will crash when you try to access the 4th element in the splitArray because there isn’t a 4th element. Either way is not good.
My point is to be safe… it would be a better approach to see how much data is actually there before you create the grid. You could get how many items there are with StringArray.Length minus the first two elements. These elements will define the dimensions and allow you to check their validity. This will make sure your loops won’t go out of bounds because the supplied data was wrong. It seems redundant and error prone to supply the dimension values when you can get that info from the data itself.
I still am not 100% sure what you want to accomplish here. It looks like a search of some form. This is what I am picturing…
Looking at your (previous) screen shots it appears to me that after you type into the Serial # text box and click the “Search Txt Files” button it will search for data that came from the input string i.e. “PLX51…” and then have the grid display the “filtered” results that match (or are LIKE) what’s in the Serial # textbox. If this is true, I would ignore the RXCX vales and put the data in a single column. Then wire up an OnKeyPress event for the text box to filter the grid whenever the user types into the Serial # text box.
Otherwise I am lost as to why you would need to create the data in the fashion described. Just because the input has unnecessary data… doesn’t mean you have to use it. Just a thought.
string inputString = "2,2,R1C1=211,R1C2=212,R2C1=213,R2C2=214";
string[] splitArray = inputString.Split(',');
int totalRows = int.Parse(splitArray[0]);
int totalCols = int.Parse(splitArray[1]);
int itemIndex = 2;
// add the columns
for (int i = 0; i < totalCols; i++)
{
dataGridView1.Columns.Add("Col", "Col");
}
// add the rows
dataGridView1.Rows.Add(totalRows);
for (int i = 0; i < totalRows; i++)
{
for (int j = 0; j < totalCols; j++)
{
dataGridView1.Rows[i].Cells[j].Value = splitArray[itemIndex];
itemIndex++;
}
}
I have the following code:
for (int i = 0; i < COLUMNS.Count; i++)
{
DataGridViewColumn column = new DataGridViewColumn()
{
Name = COLUMNS.ElementAt(i).Key,
HeaderText = COLUMNS.ElementAt(i).Value,
Width = 60
};
operationsDataGridView.Columns.Add(column);
}
I hope it's clear enough, I'm looping through a Dictionary of Column Name and Column Headers, and adding them as DataGridViewColumn instances to the DataGridView.
However, the program is looping only once, when it should loop 9 times (I've already debugged it, and COLUMNS.Count is, in fact, 9)
Therefore, only the first column is added, as it can be seen in the image:
As for the debugging output, these strange messages appear:
I'm sure it has something to do with this problem.
Interesting Fact!
If I change my code to:
for (int i = 0; i < COLUMNS.Count; i++)
{
operationsDataGridView.Columns.Add(COLUMNS.ElementAt(i).Key,
COLUMNS.ElementAt(i).Value);
}
(Which I think, is esentially the same), the program works fine!!
I was able to reproduce this error on my end, but I was getting an exception as well about "At least one of the DataGridView control's columns has no cell template."
If you change your loop to DataGridViewColumn column = new DataGridViewTextBoxColumn() it will probably work (fixed it on my end at least). Looks like the .add method with the two parameters defaults to this type of column.
I'm trying to display the table of m*n cells with some text in each cell, and the background colors of each cell could be different.
Am I right the dataGridView component could be used exactly for this purpose?
If yes, then how to make the dataGridView to contain more then just one empty row? Let's say I want it 5*5 cells and the cells could be empty.
You can add values to a DataGridView control in many ways: from a database, from a Collection (Array, DataTable, etc.), directly row by row, etc. In each cell you can put the (string) values you want, including ""/empty. Here you have a sample code to get some inspiration:
int count = 0;
int maxCount = 5;
do
{
count = count + 1;
//dataGridView1.Rows.Add("col1", "col2", "col3", "col4", "col5");
dataGridView1.Rows.Add(); //For adding empty rows, you can use this one
} while(count < maxCount);
dataGridView1[1, 2].Style.BackColor = Color.Yellow;
dataGridView1[3, 1].Style.BackColor = Color.Yellow;
dataGridView1[4, 4].Style.BackColor = Color.Yellow;
It takes dataGridView1 (a DataGridView with 5 columns added via "Design View"), adds 5 rows to it and colors the background of various cells.
I have a ListView which is bound to a DataTable. I would like to iterate over the DataTable's rows and access their data. I figured, to do this, I would simply iterate over the ListViewDataItems in the ListView. To test that I am properly accessing the data, I tried the following code, which should simply print the string at column 0 for each row.
for (int i = 0; i < MyListView.Items.Count; i++)
{
ListViewDataItem item = MyListView.Items[i];
DataRow row = (DataRow) item.DataItem;
Response.Write(row[0]);
}
However, nothing is printed. To verify that the ListView is not empty (which it shouldn't be as the data is properly rendered on my aspx page), I tried this:
Response.Write(MyListView.Items.Count);
This prints the number 16, which is correct as there are 16 rows in my ListView. I'm guessing I'm just not accessing the data correctly. I'd appreciate some insight on this.
The best way is to stop on breakpoint (at line DataRow row = (DataRow) item.DataItem;) and simply to check what you have .
for example like here :http://msdn.microsoft.com/en-us/library/ms173083(v=VS.90).aspx
I decided the best solution was to just iterate over the data directly in the DataTable rather than the ListViewDataItems.
for (int i = 0; i < myTable.Rows.Count; i++)
{
for (int j = 0; j < myTable.Columns.Count; j++)
{
object data = data.Rows[i][j];
// do stuff with data
}
}
For anyone still seeking the correct answer to this question, the following code will work (VB.NET):
Dim di as ListViewDataItem
For Each di in MyListView.Items
Response.Write(CType(di.FindControl("ExampleLabel"), Label).Text)
Next
Just substitute the Response.Write line with whatever you wanted to do to each list item. The example line is looking for a control called 'ExampleLabel', casts it back to a label then writes the text value onto the page.
Easily adapted to C# for anyone proficient (not I alas).
I need to use a the DataGridView control to display a large number of columns. I have a DataGridViewCell class that specifies a custom Paint method for each cell. I have added the columns like so...
int ColumnCount = 5000;
DataGridViewTextBoxCell cell = new DataGridViewTextBoxCell();
for (int i = 0; i < ColumnCount; i++)
{
dataGridView1.Columns.Add(new DataGridViewColumn() { CellTemplate = cell, FillWeight = 1 });
}
The problem is, this takes ages to add all the columns, much longer than it should really take. When I add the columns I can see the size of the scroll bar at the bottom of the DataGridView getting smaller like the grid is drawing each column each time I add one.
Does anyone know of a quicker way to add a large number of columns, or how to prevent the DataGridView updating until all the columns have been added?
I've tried disabling resizing, SuspendLayout(), and setting dataGridView1.Visible = false.
If you use the VirtualMode = TRUE for the DataGridView, you can refresh ONLY the screen portion.