Is it possible to have a custom sort/display order in a combox ? Say I want a special value "MasterValue" before all the others.
Instead of adding strings, create a class that implements IComparable and overrides ToString.
Add instances of that class to your ComboBox
The following code will do the trick.
Create a separate list of the items you want to sort and then use AddRange.
comboBox1.Items.Add("Master");
List<String> listToSort = new List<String>();
listToSort.Add("6nd");
listToSort.Add("3nd");
listToSort.Add("5nd");
listToSort.Add("4nd");
listToSort.Add("2nd");
listToSort.Sort();
comboBox1.Items.AddRange(listToSort.ToArray<String>());
Create a data source as a view (i.e. stored procedure) that returns an additional field valued 1.
Then get the data source, and add an additional row to the data view, with the additional field valued at 0.
Then sort the view, by that field initially, and then by the description of the field.
This will always then put your 'Master Value' first, then sort the others alphabetically.
private void PopulateCombo()
{
// get data view that returns 3 columns,
//master sort column set to 1, id, and description //
DataView view = GetSource();
// add a new row to the data source that has column values
// 0 for master sort column (all others are returned 1
// an appropriate ID and a description
// data view columns = master sort column, id, description
view.Table.Rows.Add(new object[] {0, 1, "MasterValue"});
// sort first by master column then description //
view.Sort = "MasterSortColumn ASC, Description ASC";
combo.DataSource = view;
combo.ValueMember = "Id";
combo.DisplayMember = "Description";
}
Related
I try to create report with a table and bind it to a list of string (about 10000 items).
I tried to create row in runtime, but it is very slow:
String[] ids = GetIds();
DetailTable.BeginInit();
foreach (String id in ids)
{
XRTableRow newRow = new XRTableRow();
XRTableCell newCell = new XRTableCell();
newCell.Text = id;
newRow.Cells.Add(newCell);
DetailTable.Rows.Add(newRow);
}
DetailTable.EndInit();
Also I tried to bind cell, but in report I can see only first row:
var ids = GetIds().Select(id => new {Id = id});
this.DataSource = ids;
IdCell.DataBindings.Add(new XRBinding("Text", DataSource, "Id"));
How I can fill my table?
I'd like to see your design view of the report too.
I am doing this as follows (on the Design view):
Put one xrTable to a DetailReport - that would be the table header, just fixed texts,
maybe some formatting (background, font, etc...),
I assume your table will have only one column.
insert another DetailReport (inside the first one by right-clicking on its name and selecting Insert Detail Report)
inside this second one put another xrTable of the same size, and number of columns
(there you will put the data)
click on the smart tag of this second DetailReport, add the datasource (a model, where your list is)
and point the DataMember to your List item.
I donĀ“t know if it will map itself to the string values of your list.
Probably not, so I'd change your List[[string]]
to e.g. a List[[MyOneColumnClass]]
where the MyOneColumnClass is just a class with only one public string Value {get; set;} Then you will point the DataMember to the field [Value] (just type the word in brackets into the xrTableCell text.
I have a Form that shows information about a purchase and within this form I have a DataGridView whose columns are dynamically generated based on a table on the database. This DGV contains information about the items in the selected purchase.
Here's an example of how I generate the columns in runtime in an existing DataGridView:
foreach (ColumnDGV columnDGV in columnsDGV)
{
DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
col.Name = columnDGV.A02_CAMPO;
col.HeaderText = columnDGV.A02_TITULO;
col.DataPropertyName = columnDGV.A02_CAMPO;
this.dataGridView.Columns.Add(col);
}
The object ColumnDGV contains information about the column to be created.
Then I select the columns' names from the columns list and perform the sql query based on those columns:
private void CarregarConteudoDGV()
{
SolicitCompraBLL solicitCompraBLL = new SolicitCompraBLL();
// Gets the columns' names to be used in the SELECT statement.
List<string> columnsNames = this.CamposDGV.Select(c => c.A02_CAMPO).ToList();
// Returns a DataTable containing the items of the selected purchase.
this.dataGridView.DataSource = solicitCompraBLL.ObterItensSolicitacao(columnsNames, this.B11_NUM);
}
When the user clicks in the save button I just iterate through all rows in the DGV and add its values to a nested List where each item is a list of string[2], where the position 0 contains the column name and position 1 its value. Then I pass this List to a method that creates the sql command to update the records.
I can already save the changes of each item in the database, but I also have to insert the added items. How do I know which items should be inserted and which ones should be updated?
When you insert an object in DataBase, generally your object don't have yet an Id. The object to be update must have their Id's existing yet. Now you should see if the object has an Id or Not. If the Id is Zero (or does not exist) then you insert it, otherwise you update it.
I have a small problem. I need to sort data in the DataGridView (WinForms application) in descending order. I apply a DataView as DataSource to myGrid:
DataView view = myDataTable.DefaultView;
view.Sort = "id DESC";
myGrid.DataSource = view;
id column is string data type, and is in ##/yy format. First part is incrementing integer, second part (after '/') is last two digits of current year. Unfortunately it has to be in this format.
After sortting it returns in this order:
9/14,8/14,7/14,6/14,5/14,4/14,3/14,2/14,10/14,1/14...
But it should be like this:
10/14,9/14,8/14,7/14,6/14,...
What would be the easiest way to solve this?
Thank you.
EDIT:
Added some more info...
You have a few options here. You can clone your table and modify the type and typecast it properly by modifying the values directly, or you can use a helper column, etc. This can be accomplished many ways. I'll give you a simple example that uses a single helper column to process the string into a date then sort in that way.
If you have some integer (I'll use a 16-bit integer as the type) and a two-digit year separated by a /, we can write it instead as follows:
// Setup a sample table to match yours
DataTable myDataTable = new DataTable();
myDataTable.Columns.Add("id", typeof(string));
// Add some values to the table
myDataTable.Rows.Add("7/14");
myDataTable.Rows.Add("4/14");
myDataTable.Rows.Add("8/14");
myDataTable.Rows.Add("3/14");
myDataTable.Rows.Add("6/14");
myDataTable.Rows.Add("10/14");
myDataTable.Rows.Add("5/14");
myDataTable.Rows.Add("2/14");
myDataTable.Rows.Add("9/14");
myDataTable.Rows.Add("1/14");
// Add a helper column with 16-bit format based on the values in id
myDataTable.Columns.Add("helper", typeof(Int16));
// Convert the value in the id column of each row to a string,
// then split this string at the '/' and get the first value.
// Convert this new value to a 16-bit integer,
// then save it in the helper column.
foreach (DataRow row in myDataTable.Rows) row["helper"] =
Convert.ToInt16(row["id"].ToString().Split('/')[0]);
// Create a view to match yours, sorting by helper column instead of id
DataView view = myDataTable.DefaultView;
view.Sort = "helper DESC";
//myGrid.DataSource = view;
// Write the output from this view
foreach (DataRow row in view.ToTable().Rows) Console.WriteLine(row["id"]);
which produces the output...
10/14
9/14
8/14
7/14
6/14
5/14
4/14
3/14
2/14
1/14
If you need to sort by year as well, you can add an additional helper column in the same manner.
I've got a datatable and one column is an integer ID foreign key to another database table.
I've got a datagridview and i'd like to use a combobox column to allow user to change value. But instead of using the integers, it would be great to use the names.
I've tried creating a simple struct with public members int ID and string Name; a dictionary and looked into enums (however values not known at compile time) but not got anything to work yet.
I was able to populate the combobox with struct values, but not able to programmatically set the selected item/index; ie, if ID "5" is in the datatable, set the combo box selected item to the struct that has an ID of 5.
So to be clear i'm wanting:
gridview datasource's fk ID's
1
2
3
Foreign Key table:
ID Name
1 Name 1
2 Name 2
3 Name 3
Datagridviewcombobox column should be loaded with three items; should display as "Name 1, Name 2, Name 3". Based on the gridview datasource's FK id, the selected item for each should match.
You can set the DataGridViewComboBoxColumn.DataSource property, and then use the ValueMember and DisplayMember properties to determine what is shown in the ComboBox. Easiest is probably to load your FK values into DataTable and use that as the data source. For your example:
// assuming your DataGridViewComboBox column is fkCol
// and your fk values are in a DataTable called fkTable
fkCol.DataSource = fkTable;
fkCol.ValueMember = "ID";
fkCol.DisplayMember = "Name";
I am not sure how you are binding your DataGridView to your initial DataTable, but you can associate the DataGridViewComboBox column with a specific column in your original DataTable using DataPropertyName:
fkCol.DataPropertyName = "ColumnName";
DataAccessLayer dal = new DataAccessLayer();
DataTable movies = dal.GetMovies();
gvMovies.DataSource = movies;
gvMovies.AllowUserToAddRows = false;
gvMovies.AllowUserToDeleteRows = false;
//Create the new combobox column and set it's DataSource to a DataTable
DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
col.DataSource = dal.GetMovieTypes(); ;
col.ValueMember = "MovieTypeID";
col.DisplayMember = "MovieType";
col.DataPropertyName = "MovieTypeID";
//Add your new combobox column to the gridview
gvMovies.Columns.Add(col);
I have a DataView object with productID and productName,
i get all items from Products Table and store them in Cache.
I want to get items that user bought in order he bought them without using another query or joining tables.
ie.
Products DataView
1. Foo
2. Foo2
3. Foo3
Filtering to ProductsBoughtByUser using RowFilter (productID in (1,3))
UserProducts DataView
1.Foo
3.Foo3
Now user first bought Foo3, how do i reorder items based on correct ( chronological ) Array. ie 3 1
Thanks
Here is the syntax for DataView.Sort:
private void SortByTwoColumns()
{
// Get the DefaultViewManager of a DataTable.
DataView view = DataTable1.DefaultView;
// By default, the first column sorted ascending.
view.Sort = "State, ZipCode DESC";
}
From your original post, it sounds like you only have Product ID and Product Name. You can't sort these in memory unless you're also retrieving a purchase/order date.
Probably the easiest thing to do would be to add the date column (PurchaseDate) to your sql statement that you're already using, then do a view.Sort = "PurchaseDate DESC";
That way, you don't have to write another statement or hit the database a second time for this sort.
Edit:
The DataRowView has integral and string indexers. e.g.:
foreach (DataRowView row in dataView)
{
var value = row["COLUMN_NAME"];
}
The column is stored as an object, so you'll have to check for null and convert to your data type