I've got a rather small table containing two columns - one is string and one is supposed to be numbers (I know, everything in a table is just "object").
Is there any way to convert the objects into for example Int or Double to be able to actually sort it in a reasonable way?
The sources for that table are two lists. I could sort the number list, but the data wouldn't match anymore.
Other idea would be to transfer the content of the lists into a multidimensional array and to sort that one but I'd prefer a solution to sort that table directly.
Anyone got an idea?
Rather than working with two lists, merge them:
public class MyRow { // rename me
public int Element { get; set; }
public int Appearances { get; set; }
}
....
var rows = new List<MyRow>();
for(...) {// loop over the two lists...
rows.Add(new MyRow {
Element =..., Appearances = ... });
}
rows.Sort((x,y) => y.Appearances.CompareTo(x.Appearances));
Then either just loop and create cells, or (easier) just set rows as the data-source for the table and let it bind itself.
Related
I'm currently working with the Atata framework and using a Kendo grid. What I'm trying to achieve is getting an IEnumerable or a collection containing all the values in a column. The kendo grid is defined as below:
public KendoGrid<TransactionGroupsRow, _> TransactionGroupsGrid { get; private set; }
public class TransactionGroupsRow : KendoGridRow<_>
{
[FindByColumnHeader("Group Name")]
public Link<_> GroupName { get; private set; }
}
I not only want a collection of all the links GroupName, I specifically want the text component of them i.e. what the link would read like on the screen.
So in this example I would want an IEnumerable containing "002999" and "003999".
Let me know if I need to provide additional detail. Thanks in advance!
There are 2 ways to do that.
Use SelectData method. It works quite fast for list of items with count <= 50.
// Just get all items:
IEnumerable<string> groupNames = page.TransactionGroupsGrid.Rows
.SelectData(x => x.GroupName.Content.Value).Value;
// Assert items:
page.TransactionGroupsGrid.Rows
.SelectData(x => x.GroupName.Content.Value).Should.Contain("002999", "003999");
The faster way is using SelectContentsByExtraXPath method. This one will work very fast even for a table with 1000 rows. But you need to specify a relative XPath to the table cell td element inside a row tr element. This can also be extracted to the page object class as a method.
// Just get all items:
IEnumerable<string> groupNames = page.TransactionGroupsGrid.Rows
.SelectContentsByExtraXPath("td[1]", "Group Names").Value;
// Assert items:
page.TransactionGroupsGrid.Rows
.SelectContentsByExtraXPath("td[1]", "Group Names").Should.Contain("002999", "003999");
You can also check Performance Practices for ControlList Atata sample project.
I am currently writing a piece of functional test (FCT) software used for testing PCBAs. The main interface between the user has a DataGridView that will be used to display all information pertaining to the functional test. I'm also transitioning from LABView to C# to develop these so I'm still learning a bit.
What I want to do at the start of the application is to show a 5 column x 100 row table for the data. I chose 100 rows to make the table fill up the window (it also looks a little better this way too).
The issue I'm having is when I try to add data to the same row. Note that the first set of data put in the grid will only be in two columns, while data added later on will span all five columns. Here's what I'm trying now to update the datagrid:
mydatagrid.RowCount = 100; //Put
int rowIndex; //variable for tracking where I'm placing data on the table
//Do some stuff that doesn't involve my datagrid
mydatagrid.Rows[rowIndex].Cells[0].Value = someData; //This line executes fine
mydatagrid.Rows[rowIndex].Cells[1].Value = someOtherData; //This throws an exception
//Do more stuff that doesn't involve my datagrid
Another method to update the table I tried was
mydatagrid.Rows.Add(somedata, someotherdata);
While this works nicely, it puts the data at the end of the table, rather than at the top.
Also, later on in the app will also need to something like this:
activaterelays.clicketyclackety();
makemeasurement();
updatedatagrid(); // This function will put data in all five columns
Maybe I am missing something trivial with the setup, at it's my first go at a DataGridView with Windows Forms.
To use indexing in rows and cells in a DatagridView, you must fill it with data first.
Try something like this:
public class MyData {
public string column1{ get; set;}
public string column2{ get; set;}
public string column3{ get; set;}
public string column4{ get; set;}
public string column5{ get; set;}
}
var data = new List<MyData>() {...}// You must insert the 100 items
//Loads the data to DatagridView, after this line you will see the DatagridView populated.
mydatagrid.DataSource = data;
//Now you can manipulate it
mydatagrid.Rows[rowIndex].Cells[0].Value = someData;
mydatagrid.Rows[rowIndex].Cells[1].Value = otherdata;
I have 2 listBoxes with BindingLists as their data sources. The idea is to make a List builder (as MSDN names it), where first listBox shows currently added columns and second listBox shows the rest of available columns. First list contains ViewColumn objects, while the other list contains strings.
I load chosen columns into first listBox from database and then I want to load the rest of available columns into the second listBox (the list itself comes from another place in database). Considering there are no limits on the number of columns, I want to do that in the fastest way possible - what would that be?
Here's some code to visualize that:
ViewTable _view;
BindingList<ViewColumn> _viewColumns = new BindingList<ViewColumn>();
BindingList<string> _detailsColumns = new BindingList<string>();
void CustomInitialize()
{
_view = //get view and its columns
_viewColumns = new BindingList<ViewColumn>(_view.Columns);
listBox_CurrentColumns.DataSource = _viewColumns;
listBox_CurrentColumns.DisplayMember = "Name";
var detailsTable = //get the list of available columns
foreach (var row in detailsTable)
{
//TODO: if _viewColumns does not contain this value, add it to _detailsColumns
_detailsColumns.Add(row.ColumnName);
}
listBox_AvailableColumns.DataSource = _detailsColumns;
}
I think you want to do something like:
_detailsColumns = _allColumns.Except(_viewColumns.Select(c => c.Name))
This should get you all entries in the _allColumns collection excluding the entries in the _viewColumns collection.
I assume here that _allColumns contains the overall collection of possible columns.
I have a text file with size about 10-20 MB.
I want to perfom this options.
1) read the text file and split.
2) move all the data in each line into a datagrid view.
3) create an addition datagridview. that the user can define which line can be visible and which not per a values of 1 column (filter).
I have written a code however however it take a long time.
reading to the first datagrid view the text takes about 40 secound.
when I tried to filter it takes about also 40-50 secound till the user filter it,
is there a way to reduce the time? what is the best way to do this kind of thing? and does using a datasource can be helpful?
Thanks,
I think its better to use linq.
Read your file like this and you have a list of file lines.
var lst = System.IO.File.ReadAllLines(FilePath).ToList();
Now you can filter your list by linq statements.
And you can simply show the list in your datagrid.
If you want to show all data in datagrid, it takes time.
You can also create a class for that purpose
public class MyLine
{
public string Line {get; set; }
public bool IsVisible { get; set; }
}
Then you can read the file and have a list or your class, like this:
var lst = System.IO.File.ReadAllLines("")
.Select(x => new MyLine() { Line = x, IsVisible = true });
Then for getting visible ones write this query:
var Visibles = lst.Where(x => x.IsVisible);
Hope it helps.
I'm trying to retrieve records from a table in MS Access 2010 using OleDbDataReader. In some cases the table I am retrieving records from has multiple records for the supplied query. For example: Two tables; Ist table has two columns - one is Name(primary key) the other contains numbers. 2nd table contains many fields; one being the Name field as the foreign key. In some cases my query matches a record that in both tables returns ONE record, but on other cases there is one record from 1st table, but many records from 2nd table. So my datareader only pulls in one of those records that populates the textboxes. So I wanted to find a way to put those multiple records into a listbox and I asked the question on this forum. The answer given was to use LINQ and "put the results in a List/IEnumerable". I wish is was only that simple. I've tried to incorporate List/IEnumerable and and I'm not only going backwards, but becoming more and more confused. My understanding is that I have to create a whole new class, constructor, set of methods, etc and create a list that will take any type(int, string, etc). IS this correct? Does my new class start with
public class myList : IEnumerable<T>
{
public IEnumerable<T> GetEnumerator()
{
foreach (object o in objects)
{
yield return 0;
}
}
}
Inside method in Form class
while (myreader.Read())
{
foreach (object o in myList) //do something
}
The T being any type whereas I would otherwise use int or string?
This is getting a bit confusing...
So, basically you have a parent child relationship in your tables.
I have a very similar tutorial which will hopefully solve your problem.
Thats how the data is read
ArrayList rowList = new ArrayList();
SqlDataReader reader = storedProcCommand.ExecuteReader();
while (reader.Read())
{
object[] values = new object[reader.FieldCount];
reader.GetValues(values);
rowList.Add(values);
}
and this is how the values are added to the ListView
orderDetailsList.Items.Clear();
foreach (object[] row in rowList)
{
string[] orderDetails = new string[row.Length];
int columnIndex = 0;
foreach (object column in row)
{
orderDetails[columnIndex++] = Convert.ToString(column);
}
ListViewItem newItem = new ListViewItem (orderDetails);
orderDetailsList.Items.Add (newItem);
}
The output is something like this...
If I understand you right, you're looking to get all records from one table (I'll call it Table2) where the name matches the name on one record in another table (Table1)? I do this a lot, using LINQ and a SQL database.
I'm assuming you already have the connection to the database. Have you created a method to retrieve the desired record from Table1? If so, you already have the name. So I would create another method like this:
public List<Table2> GetList(string name)
{
List<Table2> list = new List<Table2>();
list = db.Table2.Where(q => q.NameField = name).ToList();
return list;
}
You can then call this method when populating the controls and databind the list into whatever control you want to display the list. So something like this:
List<Table2> list = new List<Table2>();
list = GetList("This is the name from the Table1 data");
listviewcontrol.DataSource = list;
The method for filling the control with the data varies a bit depending on which control you're using. EDIT: Rwiti has some good code there for adding the data to the listview.
If you want to display just part of the data from the list of Table2 records (for example, a Location field to populate a combobox), I'd suggest something like this:
List<string> locations = new List<string>();
foreach (Table2 record in list)
{
locations.Add(record.Location);
}
comboBox1.DataSource = locations;