I am trying to do something like this but I don't know how:
I have a table in c# which I increase and decrease during runtime.
Each row contains data, that is being parsed from an object.
I want to get an access to the object that the line is parsing, some a pseudo of it would be:
if (table.row.object == selectedObject)
I can't do it from the row number or something because the rows are being removed and inserted, each time with different objects.
any ideas, please?
EDIT: I am using TableLayoutPanel to work with a table, and this is how I add rows and removes them:
I am adding rows to the table dynamically, I have set of buttons and when I click one it deletes all old rows from the table and adds new rows that are related to this button.
This is the way I add new rows:
tlp.RowCount++;
tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tlp.Controls.Add(new Label() { ... }, cellIDX, rowIDX);
// adding more columns //
and to remove old rows I loop through all rows from bottom to top, removes all related controls of the current cell, then I remove style and row num like so:
tlp.RowStyle.RemoveAt(rowNum);
tlp.RowCount--;
thank you
you can also see a previous question I had related to this subject:
C# change table row color when mouse hover
You can try having a new column in the table (call it original_row_no) and set the row values into that, before you start your insertion/deletion process. That way you can reference the row directly (this is in response to your final line which says "I can't do it from the row number or something because the rows are being removed and inserted, each time with different objects."
A better way is to have a unique id in the table and run your references against that.
It is much more easier to help if you show the code you are trying.
Related
I have a DGV that looks like this:
Each row in the DGV is a record in a database table.
I need to allow the user to edit any cell(s) they wish and then on a button click update the database with the new values. (There is a hidden column that holds the record's database table ID.)
I know I can grab the old value of a cell by reading it on the CellEnter event, then getting the new value on CellLeave (at least that's the way I know how to do it), but that's just for one cell. How do I accomplish that for multiple cells at once? One thought I had was to create a multidimensional array to store the row and column indexes and the new and old values for each edited cell and then read through the array to update the database. But I'm not sure that's the best way to go about this.
Another option I thought of was iterating through every cell in the DGV, but doing that would I be able to get both the old and new values in a cell that was edited by the user?
It is easier than you think.
There is no need to iterate over the DGV. If it is bound to a datatable (or dataset), just let the user enter and change data in the grid, and the datatable will update itself.
I know I can grab the old value of a cell by reading it on the
CellEnter event, then getting the new value on CellLeave
Unnecessary. Using the datatable you can access the original value and the new value of a cell, and compare them. See datarowversion. But if you just want to tell which rows were modified, you could simply use the datarowstate function.
Then, to update the data on the backend DB, you could use a SqlDataAdapter.
You might need some constraints on the datatable and on the grid for validation purposes (for example if some cells may not be empty). But overall, there is almost no need to access the DGV directly. Instead, you work with the datasource.
I need to delete the whole column in a DataGridView based on a certain condition. My DataGridView columns consists of numbers (1,2 and 3) the condition would be to delete all columns that does not contain (1,2 and 3). For Example if the column has only (1 and 3) it should be deleted.
How do I Overcome this? as many threads I went through only cover when you are certain of an index like below.
myGridView.columns.RemoveAt(index);
Some suggest hiding columns and thats not what I want, I want to completely remove the column from the DataGridView.
While it's better to do the job using data source of the DataGridView, but if the control is not bound to a data source, you can also use linq to get values from columns and check for some criteria, for example:
dgv1.Columns.Cast<DataGridViewColumn>()
.ToList().ForEach(c =>
{
var values = dgv1.Rows.Cast<DataGridViewRow>().Where(r => !r.IsNewRow)
.Select(r=>r.Cells[c.Index].Value).ToList();
if (!values.Contains(1)) //your custom criteria
dgv1.Columns.Remove(c);
});
Here is a really simple test. Load dgv1 this way:
dgv1.ColumnCount = 2;
dgv1.Rows.Add(1, 2);
dgv1.Rows.Add(3, 4);
Then use above code to delete columns and it just removes the last column.
I am trying to make a table programatically. So far I have managed to create the table with the relevant number of rows and columns. But the problem is that the cells do not wrap around its contents residing in them.
For example, there is a textbox, the user types something in and that word appears in the table. In my case, if the user typed in 'web', it'll appear, but if they type anything larger than 7 characters, then it does not appear.
I've currently got this in my code:
tableLayoutPanel1.Controls.Clear();
tableLayoutPanel1.ColumnStyles.Clear();
tableLayoutPanel1.RowStyles.Clear();
tableLayoutPanel1.ColumnCount = getNumber();
tableLayoutPanel1.RowCount = courseObj.Level_41.Count;
I've used clear() first to clear the table because I will soon be implementing a delete button next to the words. E.g. the user can press a button next to the relevant word to delete it.
EDIT = fixed it. Had to make the autoSize of my label be true.
I have created a Form using the VS 2013 designer.
I added a Listview control and added 13 columns via the Properties window.
I then wrote a program in C# and I am able to access all of those columns using the item.SubItems[N] construct. Also, all of those column headers appear in the Listview on the form.
Later I added 2 new columns. The new columns show up in the Listview but throw an invalid index error when I try to access them. Also the SubItems.Count does not reflect the increase of columns in the collection. I also notice that, in the form.Designer.cs file, those new columns are not there.
What can I do to make sure the designer file gets updated and my new columns are added to the collection? (note: this is not related to an 'off-by-one' error or a mistake in indexing number) Thanks in advance.
The reason for this behaviour is that the ListView Columns do not provide you with a regular matrix or grid like a Table or a DataGridView.
Instead they are what you would call a 'Jagged Array', meaning, that not all rows have the same number of columns.
So while you have provided / increased the maximum number of Columns the ListView will display, each Item has only as many SubItems as you have added.
If you add Columns at runtime you can display and access added SubItems, but only where you have actually added them to the Item. Before adding the extra SubItems they don't exist!
This is different from, say a DataGridView where you can freely assign values to each Cell, incuding those that belong to Columns you have created just in the previous line of code..
This is quite similar to the two types of Arrays, Jagged Arrays and Multidimensional Arrays..
But to get back at your title: The actual listView.Columns.Count has increased; what has not is the ListViewItem.SubItems.Count for any of the items.
I have built a program in WPF using Visual Basic that allows users to select from a series of items. The list of items may change as I add more items or remove older ones. Originally, I would just add and remove these items in the project code, and rebuild the executable.
Over time, however, the list of items grew and became tedious and impractical to maintain in the code. It occurred to me that it would be easier to store the items in a database table which the program can read, and the list can just be updated by adding and removing items from this database.
I have the database built, and I've added it as a Data Source. I have the data connection set up and everything is ready to go.
What I need to know is how to set the Content property of a label to a cell from a table in the database. I want to do this in the codebehind, not in markup (XAML).
My guess is that I will need to set up a sort of query with a for loop to find the cell I want.
The name of the database is ItemsDB. It contains a table called ItemsTable, and the fields in the table have a unique ID (key) with an AutoNumber data type. The column containing the data I want is named ItemLabel.
So, to sum it all up, I want a label to show the content from a single cell in the database, specified in the codebehind. Either C# or VB is fine.
EDIT
I guess I should've mentioned that the labels themselves actually function as buttons, and I don't really want to display a ListView if I don't have to. I know it's not helpful to not have any code posted, but I don't even know where to start, so there's no code to post.
Took a while longer than I expected, hope this is still useful. So, what you want to do is iterate through a collection and create a new Label for each row.
You will need a container for the Labels, I used WrapPanel, but you can use any Panel you want. I'm replacing your Data Source with a simple DataTable, you'll get the point from this:
foreach (DataRow row in YourItemsTable.Rows)
{
Label newLabel = new Label();
newLabel.Content = row["ItemLabel"].ToString();
// If you need some events, attach the handlers here
yourParentContainerPanel.Children.Add(newLabel);
}
This should be all you need.