assume I have 2 columns in gridview : column A and column B. I want to delete the whole row if Column B has no value. this code checks column B if it doesn't have any value. next, how to enter the delete command based on the value obtained from the code ?
private void Button1_Click(object sender, EventArgs e)
{
foreach (GridViewRowInfo row in DGV1.Rows)
{
if (row.Cells[1].Value == null || Convert.ToString(row.Cells[1].Value) == string.Empty)
{
MessageBox.Show("Null value");
}
}
}
Hopefully I can offer a couple of tips for working with RadGridView or really most any grid view. First, use BeginInvoke to avoid blocking the Click message which allows the UI thread to return from the click handler (mouse returns to the up position, any new button state is painted).
private void buttonRemove_Click(object sender, EventArgs e)
{
// Do not block the click event.
BeginInvoke((MethodInvoker)delegate
{
onButtonRemove();
});
}
Next make an array of records (or rows) that need to be removed. If your view is bound to a DataSource this is especially easy using System.Linq. Then simply remove from DataSource.
void onButtonRemove()
{
// Perform Linq query to see what needs to be removed
var removes =
DataSource
.Where(record => string.IsNullOrWhiteSpace(record.ColumnB));
// Cast to an array before iterating to
// avoid "CollectionWasModified" exception.
foreach (var record in removes.ToArray())
{
DataSource.Remove(record);
}
}
This particular code defines a row with this Record class:
class Record
{
public string ColumnA { get; set; } = "SomeValue";
public string ColumnB { get; set; }
}
If you were using a Winforms DataGridView it could initialize like this:
BindingList<Record> DataSource = new BindingList<Record>();
private void InitializeDataGridView()
{
dataGridView1.AllowUserToAddRows = false;
dataGridView1.DataSource = DataSource;
// Add one or more records to auto-create columns.
DataSource.Add(new Record { ColumnB = "Not empty or null"});
DataSource.Add(new Record { ColumnB = String.Empty});
DataSource.Add(new Record { ColumnB = null});
// Column formatting
dataGridView1.Columns[nameof(Record.ColumnA)].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns[nameof(Record.ColumnB)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
Your post is for Telerik.WinControls.UI.RadGridView but the initialization is very similar:
BindingList<Record> DataSource = new BindingList<Record>();
private void InitializeDataGridView()
{
DGV1.DataSource = DataSource;
// Add one or more records to auto-create columns.
DataSource.Add(new Record { ColumnB = "Not empty or null"});
DataSource.Add(new Record { ColumnB = String.Empty});
DataSource.Add(new Record { ColumnB = null});
// Column formatting
DGV1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
}
Hope this helps get you where you want to be.
Related
My group is having trouble getting this combobox and datagridview to talk to each other. What is supposed to happen is that when you select a name from the combobox, any open incidents with a tech id attached are supposed to appear. We've got the filters working but we can't seem to get the two to talk to one another. Here's the code we have so far:
public partial class frmIncidentMaintenance : Form
{
public Incident incident;
public frmIncidentMaintenance()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
TechSupportEntities techSupport = new TechSupportEntities();
var customers = (from customer in techSupport.Customers
orderby customer.Name
select new { customer.CustomerID, customer.Name
}).Distinct();
cmbCustomersBindingSource.DataSource = customers.ToList();
cmbCustomersBindingSource.DisplayMember = "Name";
cmbCustomersBindingSource.ValueMember = "CustomerID";
var products = from customer in techSupport.Customers
from incident in customer.Incidents
where incident.TechID != null
where incident.DateClosed == null
select new
{
incident.ProductCode,
incident.TechID,
incident.Title,
incident.DateOpened,
incident.DateClosed,
incident.Description
};
dataGridView1.DataSource = products.ToList();
}
private void cmbCustomers_SelectedIndexChanged(object sender, EventArgs
e)
{
}
private void dataGridView_CellContentClick(object sender,
DataGridViewCellEventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
Any help would be appreciated.
private void cmbCustomers_SelectedIndexChanged(object sender, EventArgs
e)
{
//This is the string for your tech id
string tech_id = combobox.SelectedItem.ToString();
//Searches the datagridview
int rowIndex =0;
foreach(DataGridViewRow row in [name of grid here])
{
//matches tech-id to gridrow value
if(tech_id == row.Cells[//Cell for tech_id].Value.ToString())
{
//Looks for open incidents (ill guess a numberical value 1 or 0
int open_close_value = Convert.ToInt16(row.Cells[openvalue]contains this data].value.ToString());
if(open_close_value == value your looking for)
{
//rowindex will give you the row of the gridview
rowindex = row.Index;
string incident = row.Cells[you incident].Value.ToString();
// for pushing data to be displayed in textboxes make it
// easier on yourself and allow the search engine to pull
//all incidents that are open with that tech_id add them to a list
//this will add the row number plus the incident
Listbox1.Items.Add(rowindex+","+incident);
//now on listbox1 selectedindex change all you do is parse rowindex, and use that rownumber to pull data out of database.
// your parse string should look like this.
//string[] data = listbox1.Selectedindex.ToString().Split(new string[] {","}, StringSplitOptions.None);
//to get data from gridview
//string incident= yourGrid.Rows[data[0]].Cell[the cell you want].value.ToString();
}
private void cmbCustomers_SelectedIndexChanged(object sender, EventArgs e)
{
//This is the string for your tech id
string tech_id = combobox.SelectedItem.ToString();
//Searches the datagridview
foreach(DataGridViewRow row in [name of grid here])
{
//matches tech-id to gridrow value
if(tech_id == row.Cells[//Cell for tech_id].Value.ToString())
{
//Looks for open incidents (ill guess a numberical value 1 or 0
int open_close_value = Convert.ToInt16(row.Cells[openvalue]contains this data].value.ToString());
if(open_close_value == value your looking for)
{
//rowindex will give you the row of the gridview
rowindex = row.Index;
string incident = row.Cells[you incident].Value.ToString();
// for pushing data to be displayed in textboxes make it
// easier on yourself and allow the search engine to pull
//all incidents that are open with that tech_id add them to a grid
//this will add the row number plus the incident
NewGrid.Rows.Add(row.Cells[0].Value, row.Cells[1].Value,row.Cells[2].Value, row.Cells[3].Value,row.Cells[4].Value,row.Cells[5].value);
//now on listbox1 selectedindex change all you do is parse rowindex, and use that rownumber to pull data out of database.
// your parse string should look like this.
//string[] data = listbox1.Selectedindex.ToString().Split(new string[] {","}, StringSplitOptions.None);
//to get data from gridview
//string incident= yourGrid.Rows[data[0]].Cell[the cell you want].value.ToString();
}
I have the following class which fills a list as shown bellow from an event when a button bound to each column is clicked on a DataGridView called MenuGrid:
public class orderedfood
{
public string price;
public string item;
}
List<orderedfood> order = new List<orderedfood>();
private void MenuGrid_CellClick(object sender, DataGridViewCellEventArgs e)
{
order.Add(new orderedfood { item = MenuGrid.Rows[e.RowIndex].Cells[1].Value.ToString(), price = subtotal.ToString() });
}
This MenuGrid has the following format:
What I want to do is to reload the DataGridView bound to the order List, hence I tried the following code:
MenuGrid.DataSource = null;
MenuGrid.Rows.Clear();
for (int i = 0; i < order.Count; i++)
{
MenuGrid.Rows.Add(order[i].item, order[i].price);
}
MenuGrid.Refresh();
This gives the following output, which is not what I want:
The final screenshot is correct on the number of rows but it doesn't include the name and the price of the the item.
Any suggestions?
Dont set DataSource to null. And also you can try this inside your for loop,
DataGridViewRow row = new DataGridViewRow();
dataGridView1.Rows.Add(row);
dataGridView1.Rows.Insert(0, order[i].item, order[i].price);
How can I set a value into gridview column? The thing is the column was added manually, not from the database. What I want is when the checklist value was 1 the cek22 column got ticked and when value was 0 the cek22 column was unticked. I used devexpress.
Example of my code that I used:
public void abc()
{
//select query in here
gridControl1.DataSource = dt;
//iam adding a column here
dt.Columns.Add("cek22",typeof(bool));
}
If your column is added manually then your column is working in unbound mode. So, you can just use its unbound expression. If you want to update your checklist column from cel22 then you can use CellValueChanging event.
Here is example:
var table = new DataTable();
table.Columns.AddRange(new[]
{
new DataColumn("preferred", typeof(string)),
new DataColumn("checklist", typeof(int))
});
table.Rows.Add("Director Fury", 1);
table.Rows.Add("Maria Hill", 0);
gridControl1.DataSource = table;
gridView1.PopulateColumns();
var column = new GridColumn();
column.FieldName = "cek22";
column.UnboundType = UnboundColumnType.Boolean;
column.UnboundExpression = "[checklist]";
column.Visible = true;
gridView1.Columns.Add(column);
gridView1.CellValueChanging += (sender, e) =>
{
if (e.Column.FieldName == "cek22")
gridView1.SetRowCellValue(e.RowHandle, "checklist", e.Value);
};
Here is the result:
The DevExpress Grid works with DataSource. So manipulate your DataSource and populate this to your Grid. The GridView will show this data. So if you want a check field i would recommend you to extend your DataSource with a bool Property. I don't now which DataSource you are using but if there is any bool value devexpress automatically add a checkbox column for you. If you want to link your custom column to the bool value in your DataSource you need to set the FieldName Property of the Column to your PropertyName.
If your checklist Property is 0 your bool Property return false and vice versa. This would be the easiest solution i guess. Assumed your are using a IList as DataSource.
Small example:
public class MyDataSource()
{
public int Checklist { get; set; }
public bool Cek22
{
get { return Checklist == 1; }
}
}
private void ExplainADevExpressGrid()
{
List<MyDataSource> dataSource = new List<MyDataSource>();
dataSource.Add(new MyDataSource());
myGrid.DataSource = dataSource;
}
Alternatively, add the column as part of the data source and populate it conditionally.
private void Form1_Load(object sender, EventArgs e)
{
DataTable dataTable = GetDataTable(10);
gridControl1.DataSource = dataTable;
}
private DataTable GetDataTable(int rows = 1)
{
DataTable table = new DataTable("Table1");
table.Columns.Add("checklist", typeof(int));
table.Columns.Add("cek22", typeof(bool));
for (int i = 0; i < rows; i++)
{
DataRow row = table.NewRow();
row["checklist"] = i % 2 == 0 ? 0 : 1;
row["cek22"] = ((int)row["checklist"]) == 0 ? false : true;
table.Rows.Add(row);
}
return table;
}
I have an assignment about ListView sort by Column using C# Windows Form and the codes that I got from MSDN didn't work. Can anybody find out what's wrong with the codes? Everytime I click the ListView Column nothing happens.
Here's the code, I also added the items that will show in my ListView
private int sortColumn = -1;
private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
// Determine whether the column is the same as the last column clicked.
if (e.Column != sortColumn)
{
// Set the sort column to the new column.
sortColumn = e.Column;
// Set the sort order to ascending by default.
listView1.Sorting = SortOrder.Ascending;
}
else
{
// Determine what the last sort order was and change it.
if (listView1.Sorting == SortOrder.Ascending)
listView1.Sorting = SortOrder.Descending;
else
listView1.Sorting = SortOrder.Ascending;
}
// Call the sort method to manually sort.
listView1.Sort();
// Set the ListViewItemSorter property to a new ListViewItemComparer
// object.
this.listView1.ListViewItemSorter = new ListViewItemComparer(e.Column,
listView1.Sorting);
}
private void FillItems()
{
// Add items
ListViewItem item1 = new ListViewItem("Nipun Tomar");
item1.SubItems.Add("1");
item1.SubItems.Add("10/11/2000");
ListViewItem item2 = new ListViewItem("First Last");
item2.SubItems.Add("2");
item2.SubItems.Add("12/12/2010");
ListViewItem item3 = new ListViewItem("User User");
item3.SubItems.Add("3");
item3.SubItems.Add("12/01/1800");
ListViewItem item4 = new ListViewItem("Sample");
item4.SubItems.Add("4");
item4.SubItems.Add("05/30/1900");
// Add the items to the ListView.
listView1.Items.AddRange(
new ListViewItem[] {item1, item2, item3, item4});
}
private void Form1_Load(object sender, EventArgs e)
{
FillItems();
}
public class ListViewItemComparer : IComparer
{
private int col;
private SortOrder order;
public ListViewItemComparer()
{
col = 0;
order = SortOrder.Ascending;
}
public ListViewItemComparer(int column, SortOrder order)
{
col = column;
this.order = order;
}
public int Compare(object x, object y)
{
int returnVal= -1;
returnVal = String.Compare(((ListViewItem)x).SubItems[col].Text,
((ListViewItem)y).SubItems[col].Text);
// Determine whether the sort order is descending.
if (order == SortOrder.Descending)
// Invert the value returned by String.Compare.
returnVal *= -1;
return returnVal;
}
}
Note: I added the columns in the design form.
Here's what my assignment looks like:
You dont have any columns in your list view. They are just items. thats why the event listView1_ColumnClick never fires. (also make sure you have added this event to your list view.)
Add this at first of your Form1_Load event to initialize columns.
// set view mode to see columns
listView1.View = View.Details;
// 100 is just a length of column. HorizontalAlignment.Left starts from left side
listView1.Columns.Add("Name", 100, HorizontalAlignment.Left);
listView1.Columns.Add("Number", 100, HorizontalAlignment.Left);
listView1.Columns.Add("Date", 100, HorizontalAlignment.Left);
Now you see the columns which you can select them to sort items by that column.
Note that i just added 3 columns. so list view will show each item with 2 of their SubItems under columns by order.
As you requested to post the gif. Here is it :)
You call listView1.Sort()before setting the comparer: this.listView1.ListViewItemSorter = ...
Just invert the two lines.
Also, note that you are using string.Compare for all columns, which, I think, it's not what you want for column 3 (date)
[Edit]:
Just realized now the setting the value for ListviewItemSorter cause the LV to sort: your code seems to work even without calling listView1.Sort()
Problem must be somewhere else. Try with debugger setting breakpoints...
private void lvw_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
{
ListViewColumnSorter sorter = new ListViewColumnSorter();
sorter.SortColumn = e.Column;
sorter.Order = System.Windows.Forms.SortOrder.Ascending;
lvw.ListViewItemSorter =sorter;
lvw.Sort();
}
How do I sort a DataGridView by two columns (ascending)? I have two columns: day and status.
If I need to sort by one column, I do:
this.dataGridView1.Sort (this.dataGridView1.Columns["day"], ListSortDirection.Ascending);
But for two?
If your DataGridView is databound, you can sort your Datatable view and rebind to datatable as below:
private DataGridView dataGridView1 = new DataGridView();
private BindingSource bindingSource1 = new BindingSource();
private void Form1_Load(object sender, System.EventArgs e)
{
// Bind the DataGridView to the BindingSource
dataGridView1.DataSource = bindingSource1;
SortDataByMultiColumns(); //Sort the Data
}
private void SortDataByMultiColumns()
{
DataView view = dataTable1.DefaultView;
view.Sort = "day ASC, status DESC";
bindingSource1.DataSource = view; //rebind the data source
}
OR, without using bindingsource and binding directly to DataView:
private void SortDataByMultiColumns()
{
DataView view = ds.Tables[0].DefaultView;
view.Sort = "day ASC, status DESC";
dataGridView1.DataSource = view; //rebind the data source
}
Add a hidden column that combines the two and sort by that.
You can use the DataGridView's Sort method, but specify an argument that is an instance of a class that implements IComparer.
Here is an example of such a class:
public class MyTwoColumnComparer : System.Collections.IComparer
{
private string _SortColumnName1;
private int _SortOrderMultiplier1;
private string _SortColumnName2;
private int _SortOrderMultiplier2;
public MyTwoColumnComparer(string pSortColumnName1, SortOrder pSortOrder1, string pSortColumnName2, SortOrder pSortOrder2)
{
_SortColumnName1 = pSortColumnName1;
_SortOrderMultiplier1 = (pSortOrder1 == SortOrder.Ascending) ? 1 : -1;
_SortColumnName2 = pSortColumnName2;
_SortOrderMultiplier2 = (pSortOrder2 == SortOrder.Ascending) ? 1 : -1;
}
public int Compare(object x, object y)
{
DataGridViewRow r1 = (DataGridViewRow)x;
DataGridViewRow r2 = (DataGridViewRow)y;
int iCompareResult = _SortOrderMultiplier1 * String.Compare(r1.Cells[_SortColumnName1].Value.ToString(), r2.Cells[_SortColumnName1].Value.ToString());
if (iCompareResult == 0) iCompareResult = _SortOrderMultiplier2 * String.Compare(r1.Cells[_SortColumnName2].Value.ToString(), r2.Cells[_SortColumnName2].Value.ToString());
return iCompareResult;
}
}
Now, we might call this from a column whose SortMode is 'Programmatic' on a mouse click:
private void dgvAllMyEmployees_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
DataGridViewColumn dgvcClicked = dgvAllEmployees.Columns[e.ColumnIndex];
if (dgvcClicked.SortMode == DataGridViewColumnSortMode.Programmatic)
{
_SortOrder = (_SortOrder == SortOrder.Ascending) ? SortOrder.Descending : SortOrder.Ascending;
MyTwoColumnComparer Sort2C = new MyTwoColumnComparer(dgvcClicked.Name, _SortOrder, "LastName", SortOrder.Ascending);
dgvAllEmployees.Sort(Sort2C);
}
}
The class level variable _SortOrder helps keep track of which order to go in. One can enhance this more to remember the last two columns clicked and sort on them in the desired order.
TLDR; I have a two-line solution.
I had to do the same thing, but after researching all these complicated ways to do this by either including a separate .dll or writing my own class/methods, I knew there had to be an easier way. It turns out I was right because I figured out how to accomplish this with using only two lines of code. This worked for me.
Luckily, it turns out for us that the .NET Framework Sort() method does help us with this. The idea is that you want to sort the columns individually, but the order in which you sort them in is what will produce the desired output.
So, as an example, I have a column for file type and a column for a file name. Whenever I want to sort the data by the types, I want to make sure that the names are also sorted within each type shown.
GOAL: Sorting by type will also sort the file names alphabetically.
Data:
zxcv.css
testimg3.jpg
asdf.html
testimg2.jpg
testimg1.jpg
Sorting data by name:
mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mNameLabel.Index], ListSortDirection.Ascending);
asdf.html
testimg1.jpg
testimg2.jpg
testimg3.jpg
zxcv.css
As you can see, this will name sure that the names will be sorted accordingly, such that when I now sort by the file types, both requirements will satisfy.
Sorting data by file type:
mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mFileExtensionLabel.Index], ListSortDirection.Ascending);
zxcv.css
asdf.html
testimg1.jpg
testimg2.jpg
testimg3.jpg
Voila! It's sorted!
SOLUTION: In your case, you may want to try something like the following, and you may need to tweak it some more to have it cater to your own code.
DataGridView1.Sort(DataGridView1.Columns["status"], ListSortDirection.Ascending);
DataGridView1.Sort(DataGridView1.Columns["day"], ListSortDirection.Asscending);
This should be able to display your results by the day with its status field sorted as well.
The answer that John Kurtz provided got me close. But what I found was the when I clicked on a column once, it did indeed sort by the two columns ... In his example: dgvcClicked.Name, "LastName". So, good!!
But, if I clicked on the column again, then it would NOT sort by the opposite direction. So the column became stuck in Ascending.
To overcome this, I had to track the sort order manually. Started with this class:
public class ColumnSorting
{
public int ColumnIndex { get; set; }
public ListSortDirection Direction { get; set; }
}
Then, I added this globally scoped List:
List<ColumnSorting> _columnSortingList = new List<ColumnSorting>();
Then, in the method that does the Sort, I would
Check to see if the column index being sorted already exists in _columnSortingList. If not, add it.
If it already exists, then swap the sort order
And Bob's your uncle.
You can try this, or use custom sorting:
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (dataGridView1.Columns[e.ColumnIndex].HeaderText =="day")
{
myBindingSource.Sort = "day, hour";
}
}
I use this solution when working with bound data. This works for our users, and displays the current sort criteria. All sorts are only in ascending order.
Add a CheckBox, a TextBox, a ColumnHeaderMouseClick event, and code as shown. The CheckBox will toggle the TextBox's visibility, and clicking on any column header will add the sort criteria to the TextBox. To clear the TextBox, just double click in it.
private void FooDataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if(chkMultiSort.Checked == true)
{
string columnHeader = FooDataGridView.Columns[e.ColumnIndex].DataPropertyName;
txtMultiSort.Text += (columnHeader + ", ");
try
{
FooBindingSource.Sort = txtMultiSort.Text.Remove(txtMultiSort.Text.Length - 2);
}
catch
{
MessageBox.Show("Invalid Sort Data", "Information", MessageBoxButtons.OK, MessageBoxIcon.None);
txtMultiSort.Text = String.Empty;
}
}
}
private void ChkMultiSort_CheckedChanged(object sender, EventArgs e)
{
if(chkMultiSort.Checked == true)
{
txtMultiSort.Visible = true;
}
else
{
txtMultiSort.Visible = false;
txtMultiSort.Text = String.Empty;
}
}
private void TxtMultiSort_DoubleClick(object sender, EventArgs e)
{
txtMultiSort.Text = String.Empty;
}
Here is a refinement on the IComparer class from #John Kurtz, which supports mutliple columns and sorting by numbers or dates.
public static void SortOnMultipleColumns(DataGridView dgv, Dictionary<string /*Column Name*/, ColumnSortInfo> sortingColumns)
{
// Show the glyphs
foreach (DataGridViewColumn col in dgv.Columns)
{
System.Windows.Forms.SortOrder sortOrder = System.Windows.Forms.SortOrder.None;
foreach (var kvp in sortingColumns)
{
if (kvp.Key == col.Name)
{
sortOrder = kvp.Value.SortOrder;
break;
}
}
col.HeaderCell.SortGlyphDirection = sortOrder;
}
// Sort the grid
MultiColumnCompararor multiColumnCompararor = new MultiColumnCompararor(sortingColumns);
dgv.Sort(multiColumnCompararor);
}
public class ColumnSortInfo
{
public enum ValueConversion { ToString, ToNumber, ToDate}
public ColumnSortInfo(System.Windows.Forms.SortOrder sortOrder, ValueConversion valueConversion = ValueConversion.ToString)
{
SortOrder = sortOrder;
MyValueConversion = valueConversion;
SortOrderMultiplier = (SortOrder == SortOrder.Ascending) ? 1 : -1;
}
public System.Windows.Forms.SortOrder SortOrder { get; set; }
public int SortOrderMultiplier { get; }
public ValueConversion MyValueConversion { get; set; }
public static double StringToDouble(string sVal)
{
if (Double.TryParse(sVal, out double dVal))
{
return dVal;
}
return 0;
}
public static DateTime StringToDateTime(string sVal)
{
if (DateTime.TryParse(sVal, out DateTime dt))
{
return dt;
}
return DateTime.MinValue;
}
}
private class MultiColumnCompararor : System.Collections.IComparer
{
IDictionary<string /*Column Name*/, ColumnSortInfo> _sortingColumns;
public MultiColumnCompararor(IDictionary<string /*Column Name*/, ColumnSortInfo> sortingColumns)
{
_sortingColumns = sortingColumns;
}
public int Compare(object x, object y)
{
try
{
DataGridViewRow r1 = (DataGridViewRow)x;
DataGridViewRow r2 = (DataGridViewRow)y;
foreach (var kvp in _sortingColumns)
{
string colName = kvp.Key;
ColumnSortInfo csi = kvp.Value;
string sVal1 = r1.Cells[colName].Value?.ToString().Trim()??"";
string sVal2 = r2.Cells[colName].Value?.ToString().Trim()??"";
int iCompareResult = 0;
switch (csi.MyValueConversion)
{
case ColumnSortInfo.ValueConversion.ToString:
iCompareResult = String.Compare(sVal1, sVal2);
break;
case ColumnSortInfo.ValueConversion.ToNumber:
double d1 = ColumnSortInfo.StringToDouble(sVal1);
double d2 = ColumnSortInfo.StringToDouble(sVal2);
iCompareResult = ((d1 == d2) ? 0 : ((d1 > d2) ? 1 : -1));
break;
case ColumnSortInfo.ValueConversion.ToDate:
DateTime dt1 = ColumnSortInfo.StringToDateTime(sVal1);
DateTime dt2 = ColumnSortInfo.StringToDateTime(sVal2);
iCompareResult = ((dt1 == dt2) ? 0 : ((dt1 > dt2) ? 1 : -1));
break;
default:
break;
}
iCompareResult = csi.SortOrderMultiplier * iCompareResult;
if (iCompareResult != 0) { return iCompareResult; }
}
return 0;
}
catch (Exception ex)
{
return 0;
}
}
}
Usage:
Dictionary<String, ColumnSortInfo> sortingColumns = new Dictionary<String, ColumnSortInfo>
{ {"policyNumber", new ColumnSortInfo(System.Windows.Forms.SortOrder.Ascending)},
{"MessageId", new ColumnSortInfo(System.Windows.Forms.SortOrder.Descending, ColumnSortInfo.ValueConversion.ToNumber)},
{"CreationDate", new ColumnSortInfo(System.Windows.Forms.SortOrder.Ascending, ColumnSortInfo.ValueConversion.ToDate)}};
CsUtils.SortOnMultipleColumns(dgv, sortingColumns);