Add auto number column to list view table? - c#

I've a ListView that fetch data from SQL compact CE database. I've an ID column in the database already , but I want to add an auto number column in the list view itself.
I want to replace the ID column with an auto number column (I don't want the number to be saved in the database itself , I just want to sort the rows in the list view)
http://i.imgur.com/nenhN2w.jpg
The code I'm using :
ListViewItem item = new ListViewItem(sqldr["ID"].ToString());
item.SubItems.Add(sqldr["EnglishWord"].ToString());
item.SubItems.Add(sqldr["EnglishDesc"].ToString());
item.SubItems.Add(sqldr["ArabicDesc"].ToString());
item.SubItems.Add(sqldr["ArabicWord"].ToString());
item.SubItems.Add(sqldr["Subject"].ToString());
listView1.Items.Add(item);
I'm using C# - Windows Application - WinForms

You could do something like this:
ListViewItem item = listView.Items.Add((listView.Items.Count + 1).ToString());
However the problem here is you may get duplicate numbers if you add/remove, if you did this in one go never to be repeated it'd be less of an issue.
To avoid this you'd probably need some kind of class global counter, and then do:
int counter = 0;
ListViewItem item = listView.Items.Add((++counter).ToString());
This would ensure that any new addition to the list will get the next number up, so it's always increasing.

Related

empty a specific column of numbers from the datagridview

Question:
How to empty specific column of numbers from datagridview? (i mean erase the values without header, not delete the column).
for example FROM THIS TO THAT, so i dont need to do it manually
How i created the datagridview:
i created a database table, with 5 ID's all of datatype "int", i connected the datagridview through DataSource, bindingsource. And when i put values in the table and press button:(button code below)
table1BindingSource2.EndEdit();
table1TableAdapter2.Update(database1DataSet8.Table1;
It will save the values into DataTable.
For example the first ID in the table is : Konduktivita1[µS_cm-1]
What i think is neccesery is to actually delete the values from DataTable but i dont how to do it.
It would be easier if you provided some kind of code, but let's try something like this.
var sourceList = dataGridName.ItemsSource as List<sqlTable>; //or whatever your data is called
foreach (var item in sourceList)
{
item.Konduktiva1 = null; // or 0
}

How to read all new rows from database?

I am trying to read all new rows that are added to the database on a timer.
First I read the entire database and save it to a local data table, but I want to read all new rows that are added to the database. Here is how I'm trying to read new rows:
string accessDB1 = string.Format("SELECT * FROM {0} ORDER BY ID DESC", tableName);
setupaccessDB(accessDB1);
int dTRows = localDataTable.Rows.Count + 1;
localDataTable.Rows.Add();
using (readNext = command.ExecuteReader())
{
while (readNext.Read())
{
for (int xyz = 0; xyz < localDataTable.Columns.Count; xyz++)
{
// Code
}
break;
}
}
If only 1 row is added within the timer then this works fine, but when multiple rows are added this only reads the latest row.
So is there any way I can read all added rows.
I am using OledbDataReader.
Thanks in advance
For most tables the primary key is based an incremental value. This can be a very simple integer that is incremented by one, but it could also be a datetime based guid.
Anyway if you know the id of the last record. You can simple ask for all records that have a 'higher' id. In that way you do get the new records, but what about updated records? If you also want those you might want to use a column that contains a datetime value.
A little bit more trickier are records that are deleted from the database. You can't retrieve those with a basic query. You could solve that by setting a TTL for each record you retrieve from the database much like a cache. When the record is 'expired', you try to retrieve it again.
Some databases like Microsoft SQL Server also provide more advanced options into this regard. You can use query notifications via the broker services or enable change tracking on your database. The last one can even indicate what was the last action per record (insert, update or delete).
Your immediate problem lies here:
while (readNext.Read())
{
doSomething();
break;
}
This is what your loop basically boils down to. That break is going to exit the loop after processing the first item, regardless of how many items there are.
The first item, in this case, will probably be the last one added (as you state it is) since you're sorting by descending ID.
In terms of reading only newly added rows, there are a variety of ways to do it, some which will depend on the DBMS that you're using.
Perhaps the simplest and most portable would be to add an extra column processed which is set to false when a row is first added.
That way, you can simply have a query that looks for those records and, for each, process them and set the column to true.
In fact, you could use triggers to do this (force the flag to false on insertion) which opens up the possibility for doing it with updates as well.
Tracking deletions is a little more difficult but still achievable. You could have a trigger which actually writes the record to a separate table before deleting it so that your processing code has access to those details as well.
The following works
using (readNext = command.ExecuteReader())
{
while (readNext.Read())
{
abc = readNext.FieldCount;
for (int s = 1; s < abc; s++)
{
var nextValue = readNext.GetValue(s);
}
}
}
The For Loop reads the current row and then the While Loop moves onto the next row

C# SubItems Issue

I'm a student learning C#, with previous experiences with VB. I'm trying to use a list view to display three pieces of information in three separate columns. The Item is a decimal (Object = 3.50m), and the subItems are the quantity and a price. I have managed to get the first two columns showing the data with:-
var item = lsvstarter.Items.Add(cmbStarter.Text);
item.SubItems.Add(cmbStrQuantity.Text);
The third column should show the worth of the item multiplied by the quantity, so it would be
1st Column "3.50"
2nd Column "3"
3rd Column (3.50 * 3) "10.5"
But the method I used for the first subitem will not work for the variable that should be displayed by the third column. This being
item.SubItems.Add(Startertotal);
The ListView includes 3 columns. I had this program working on VB since the scenario is the same but using translators didn't work successfully. All of the objects in the Design view are the same.
Also the calculation for the "Startertotal" variable has already been calculated in a loop beforehand. Does anyone know what I'm doing wrong and the fix?
MSDN: SubItems.Add takes either a string or a SubItem as its first parameter.
So you need to change the numeric value to a string in one way or another:
item.SubItems.Add(Startertotal + " ");
item.SubItems.Add(Startertotal + "");
item.SubItems.Add(Startertotal.ToString());
item.SubItems.Add(Startertotal.ToString("###0,00"));
item.SubItems.Add(String.Format("Sum: {0} ", Startertotal));
or whatever formatting you want..

How can I modify a repeater to not show data for every row bound to it?

I have a stored proc that returns 4 rows in a table. Each row corresponds to a day a person is staying at a hotel, so when I bind a repeater to it, 4 rows show up. Two of the rows are the same room and the other two are the same room. I want to display credit card information, but not for each individual room, only for every set of rooms that is the same, so it would look something like this:
12/7/2011 Room 1
12/8/2011 Room 1
Credit Card Info
12/7/2011 Room 2
12/8/2011 Room 2
Credit Card Info
I don't want to combine Room information and credit information into a one row each. How can I get this to format the way I want it to?
Currently I am displaying Room Information in an ItemTemplate and inside the ItemTemplate is a tr and td's.
You basically have two options: you can pre-process the data so that what is bound to the repeater represents what you want to present to the user - DJ KRAZE has shown one way to do that.
The other option would be to add an ItemDataBound event handler and manipulate the data and/or the current row at that point.
One drawback of the 2nd approach is that you need access to the prior row in order to make your decision - that may complicate things, especially if you have any paging of the results.
//Create either a HashTable()
//or a Dictionary<int, string[]> I would personally use a Dictionary<>
//create an instance of what ever collection you want to use or array
//List<string>
//Dictionary<int, string[]>() using the room number as the key
// you would add the values to either the List<> or a String[] array or a Dictionary
keey in mind that if you want to create a dynamic string[] array and you do not know how many elements you are going to add just use a List<> or Dictionary<int,string>
and you can always convert that object using .ToArray
so for example
List<string> lstRoomList = new List<string>();
string[] arrayRoom = {};
if you have a DataReader for example and you are doing something like
while (yourdataReader.Read())
{
// here you can decide how you are going to work with the data you
lstRoomList.Add(datareader["roomnubmer"] + " " + datareader[CreditCarInfo];
}
at the end you could assign the values of that list to a dynamic array
arrayRoom = kstRoomList.ToArray(); I would really need to see what you are using and how you are returning the StoredProc results..

More Time taking While retriving data from the ListView in c#

Consider the ListView item Having two columns with more than 35,000 rows inserted already. Now the user selects the any 30,000 rows from the ListView. I want all the Selected Items data let's Say (Item,Subitems)
Here is my code.
ListView Name : lstViewData
List<string> l_lstData = new List<String>();
for(int l_nItem =0;l_nItem<lstViewData.SelectedItems.Count;l_nItem++)
{
l_lstData.Add(lstViewData.SelectedItems[l_nItem].Text+
lstViewData.SelectedItems[l_nItem].SubItems[1].Text);
}
It Will take more than Half an hour in my PC(Configuration - IntelCore2Duo #2.40GHZ).Since the no. of selected items is morethan 30,000 in ListView
Kindly tell me the solution If any one knows?
You are using the + operator:
l_lstData.Add(lstViewData.SelectedItems[l_nItem].Text+lstViewData.SelectedItems[l_nItem].SubItems[1].Text);
you should NEVER in a case where there is a lot of operations use the + operator on strings, as they are immutable. You should use a StringBuilder.
l_lstData.Add(sbuilder.Append(lstViewData.Seleteditems[l_nItem].Text).Append(lstViewData.SelectedItems[l_nItem].SubItems[1].Text).ToString());
sbuilder.Remove(0, sbuilder.Length);
where sbuilder is an instance of StringBuilder

Categories