how to sort a datagridview by 2 columns
up vote
12
down vote
favorite
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?
c# winforms datagridview
add a comment |
up vote
12
down vote
favorite
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?
c# winforms datagridview
i dont think you can sort them both together, you can call your code for 2 columns to order it by day first, and by another column later
– Moonlight
Jan 17 '12 at 8:07
you can have a look here: social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/…
– Adrian Fâciu
Jan 17 '12 at 8:09
Are you using WinForms or something else?
– Anatolii Gabuza
Jan 17 '12 at 8:12
yes, I m using winforms
– user1112847
Jan 17 '12 at 8:14
add a comment |
up vote
12
down vote
favorite
up vote
12
down vote
favorite
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?
c# winforms datagridview
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?
c# winforms datagridview
c# winforms datagridview
edited Jan 17 '12 at 8:24
Brissles
3,4441728
3,4441728
asked Jan 17 '12 at 8:05
user1112847
1191210
1191210
i dont think you can sort them both together, you can call your code for 2 columns to order it by day first, and by another column later
– Moonlight
Jan 17 '12 at 8:07
you can have a look here: social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/…
– Adrian Fâciu
Jan 17 '12 at 8:09
Are you using WinForms or something else?
– Anatolii Gabuza
Jan 17 '12 at 8:12
yes, I m using winforms
– user1112847
Jan 17 '12 at 8:14
add a comment |
i dont think you can sort them both together, you can call your code for 2 columns to order it by day first, and by another column later
– Moonlight
Jan 17 '12 at 8:07
you can have a look here: social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/…
– Adrian Fâciu
Jan 17 '12 at 8:09
Are you using WinForms or something else?
– Anatolii Gabuza
Jan 17 '12 at 8:12
yes, I m using winforms
– user1112847
Jan 17 '12 at 8:14
i dont think you can sort them both together, you can call your code for 2 columns to order it by day first, and by another column later
– Moonlight
Jan 17 '12 at 8:07
i dont think you can sort them both together, you can call your code for 2 columns to order it by day first, and by another column later
– Moonlight
Jan 17 '12 at 8:07
you can have a look here: social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/…
– Adrian Fâciu
Jan 17 '12 at 8:09
you can have a look here: social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/…
– Adrian Fâciu
Jan 17 '12 at 8:09
Are you using WinForms or something else?
– Anatolii Gabuza
Jan 17 '12 at 8:12
Are you using WinForms or something else?
– Anatolii Gabuza
Jan 17 '12 at 8:12
yes, I m using winforms
– user1112847
Jan 17 '12 at 8:14
yes, I m using winforms
– user1112847
Jan 17 '12 at 8:14
add a comment |
6 Answers
6
active
oldest
votes
up vote
9
down vote
accepted
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
}
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:29
@user1112847 I dont understand..if u r asking if inplace of bindingSource1 your ds.Tables[0] code will work fine then yes, I think so it should work fine..
– VS1
Jan 17 '12 at 8:37
add a comment |
up vote
6
down vote
Add a hidden column that combines the two and sort by that.
1
It is a good idea but wont work if you want to sort one column asc and another desc.
– ᔕIᑎᗩ KᗩᖇᐯᗩᑎᗪI
Feb 27 '17 at 15:17
add a comment |
up vote
4
down vote
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.
Seems it wont work if there is a value testimg2.css in your example
– user3423149
Jun 29 '15 at 8:22
add a comment |
up vote
2
down vote
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.
This should be the answer
– Casey Crookston
Jan 9 at 22:50
ok but wait.... where is MyTwoColumnComparer.Compare ever called?
– Casey Crookston
Jan 9 at 23:19
On second thought... I can't get this to work. It sorts the first time I click on a column, (ascending) but it won't sort descending if I click on it again
– Casey Crookston
Jan 9 at 23:30
This answer got me SO CLOSE!! I added a new answer that builds on this answer and solves the problem of a column not being to toggle between Ascending and Descending when clicking on it.
– Casey Crookston
Jan 11 at 16:22
add a comment |
up vote
0
down vote
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";
}
}
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:30
ds.Tables[0].DefaultView.Sort = "day, hour";
– pistipanko
Jan 17 '12 at 8:36
add a comment |
up vote
0
down vote
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.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f8891390%2fhow-to-sort-a-datagridview-by-2-columns%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
9
down vote
accepted
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
}
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:29
@user1112847 I dont understand..if u r asking if inplace of bindingSource1 your ds.Tables[0] code will work fine then yes, I think so it should work fine..
– VS1
Jan 17 '12 at 8:37
add a comment |
up vote
9
down vote
accepted
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
}
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:29
@user1112847 I dont understand..if u r asking if inplace of bindingSource1 your ds.Tables[0] code will work fine then yes, I think so it should work fine..
– VS1
Jan 17 '12 at 8:37
add a comment |
up vote
9
down vote
accepted
up vote
9
down vote
accepted
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
}
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
}
edited Jan 17 '12 at 8:43
answered Jan 17 '12 at 8:22
VS1
5,88732852
5,88732852
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:29
@user1112847 I dont understand..if u r asking if inplace of bindingSource1 your ds.Tables[0] code will work fine then yes, I think so it should work fine..
– VS1
Jan 17 '12 at 8:37
add a comment |
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:29
@user1112847 I dont understand..if u r asking if inplace of bindingSource1 your ds.Tables[0] code will work fine then yes, I think so it should work fine..
– VS1
Jan 17 '12 at 8:37
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:29
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:29
@user1112847 I dont understand..if u r asking if inplace of bindingSource1 your ds.Tables[0] code will work fine then yes, I think so it should work fine..
– VS1
Jan 17 '12 at 8:37
@user1112847 I dont understand..if u r asking if inplace of bindingSource1 your ds.Tables[0] code will work fine then yes, I think so it should work fine..
– VS1
Jan 17 '12 at 8:37
add a comment |
up vote
6
down vote
Add a hidden column that combines the two and sort by that.
1
It is a good idea but wont work if you want to sort one column asc and another desc.
– ᔕIᑎᗩ KᗩᖇᐯᗩᑎᗪI
Feb 27 '17 at 15:17
add a comment |
up vote
6
down vote
Add a hidden column that combines the two and sort by that.
1
It is a good idea but wont work if you want to sort one column asc and another desc.
– ᔕIᑎᗩ KᗩᖇᐯᗩᑎᗪI
Feb 27 '17 at 15:17
add a comment |
up vote
6
down vote
up vote
6
down vote
Add a hidden column that combines the two and sort by that.
Add a hidden column that combines the two and sort by that.
answered Jan 17 '12 at 8:11
linkerro
3,30822026
3,30822026
1
It is a good idea but wont work if you want to sort one column asc and another desc.
– ᔕIᑎᗩ KᗩᖇᐯᗩᑎᗪI
Feb 27 '17 at 15:17
add a comment |
1
It is a good idea but wont work if you want to sort one column asc and another desc.
– ᔕIᑎᗩ KᗩᖇᐯᗩᑎᗪI
Feb 27 '17 at 15:17
1
1
It is a good idea but wont work if you want to sort one column asc and another desc.
– ᔕIᑎᗩ KᗩᖇᐯᗩᑎᗪI
Feb 27 '17 at 15:17
It is a good idea but wont work if you want to sort one column asc and another desc.
– ᔕIᑎᗩ KᗩᖇᐯᗩᑎᗪI
Feb 27 '17 at 15:17
add a comment |
up vote
4
down vote
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.
Seems it wont work if there is a value testimg2.css in your example
– user3423149
Jun 29 '15 at 8:22
add a comment |
up vote
4
down vote
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.
Seems it wont work if there is a value testimg2.css in your example
– user3423149
Jun 29 '15 at 8:22
add a comment |
up vote
4
down vote
up vote
4
down vote
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.
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.
edited Nov 4 '17 at 14:51
Imran Ali Khan
4,395133768
4,395133768
answered Sep 2 '14 at 16:39
susieloo_
465513
465513
Seems it wont work if there is a value testimg2.css in your example
– user3423149
Jun 29 '15 at 8:22
add a comment |
Seems it wont work if there is a value testimg2.css in your example
– user3423149
Jun 29 '15 at 8:22
Seems it wont work if there is a value testimg2.css in your example
– user3423149
Jun 29 '15 at 8:22
Seems it wont work if there is a value testimg2.css in your example
– user3423149
Jun 29 '15 at 8:22
add a comment |
up vote
2
down vote
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.
This should be the answer
– Casey Crookston
Jan 9 at 22:50
ok but wait.... where is MyTwoColumnComparer.Compare ever called?
– Casey Crookston
Jan 9 at 23:19
On second thought... I can't get this to work. It sorts the first time I click on a column, (ascending) but it won't sort descending if I click on it again
– Casey Crookston
Jan 9 at 23:30
This answer got me SO CLOSE!! I added a new answer that builds on this answer and solves the problem of a column not being to toggle between Ascending and Descending when clicking on it.
– Casey Crookston
Jan 11 at 16:22
add a comment |
up vote
2
down vote
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.
This should be the answer
– Casey Crookston
Jan 9 at 22:50
ok but wait.... where is MyTwoColumnComparer.Compare ever called?
– Casey Crookston
Jan 9 at 23:19
On second thought... I can't get this to work. It sorts the first time I click on a column, (ascending) but it won't sort descending if I click on it again
– Casey Crookston
Jan 9 at 23:30
This answer got me SO CLOSE!! I added a new answer that builds on this answer and solves the problem of a column not being to toggle between Ascending and Descending when clicking on it.
– Casey Crookston
Jan 11 at 16:22
add a comment |
up vote
2
down vote
up vote
2
down vote
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.
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.
answered Nov 30 '16 at 21:32
John Kurtz
347214
347214
This should be the answer
– Casey Crookston
Jan 9 at 22:50
ok but wait.... where is MyTwoColumnComparer.Compare ever called?
– Casey Crookston
Jan 9 at 23:19
On second thought... I can't get this to work. It sorts the first time I click on a column, (ascending) but it won't sort descending if I click on it again
– Casey Crookston
Jan 9 at 23:30
This answer got me SO CLOSE!! I added a new answer that builds on this answer and solves the problem of a column not being to toggle between Ascending and Descending when clicking on it.
– Casey Crookston
Jan 11 at 16:22
add a comment |
This should be the answer
– Casey Crookston
Jan 9 at 22:50
ok but wait.... where is MyTwoColumnComparer.Compare ever called?
– Casey Crookston
Jan 9 at 23:19
On second thought... I can't get this to work. It sorts the first time I click on a column, (ascending) but it won't sort descending if I click on it again
– Casey Crookston
Jan 9 at 23:30
This answer got me SO CLOSE!! I added a new answer that builds on this answer and solves the problem of a column not being to toggle between Ascending and Descending when clicking on it.
– Casey Crookston
Jan 11 at 16:22
This should be the answer
– Casey Crookston
Jan 9 at 22:50
This should be the answer
– Casey Crookston
Jan 9 at 22:50
ok but wait.... where is MyTwoColumnComparer.Compare ever called?
– Casey Crookston
Jan 9 at 23:19
ok but wait.... where is MyTwoColumnComparer.Compare ever called?
– Casey Crookston
Jan 9 at 23:19
On second thought... I can't get this to work. It sorts the first time I click on a column, (ascending) but it won't sort descending if I click on it again
– Casey Crookston
Jan 9 at 23:30
On second thought... I can't get this to work. It sorts the first time I click on a column, (ascending) but it won't sort descending if I click on it again
– Casey Crookston
Jan 9 at 23:30
This answer got me SO CLOSE!! I added a new answer that builds on this answer and solves the problem of a column not being to toggle between Ascending and Descending when clicking on it.
– Casey Crookston
Jan 11 at 16:22
This answer got me SO CLOSE!! I added a new answer that builds on this answer and solves the problem of a column not being to toggle between Ascending and Descending when clicking on it.
– Casey Crookston
Jan 11 at 16:22
add a comment |
up vote
0
down vote
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";
}
}
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:30
ds.Tables[0].DefaultView.Sort = "day, hour";
– pistipanko
Jan 17 '12 at 8:36
add a comment |
up vote
0
down vote
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";
}
}
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:30
ds.Tables[0].DefaultView.Sort = "day, hour";
– pistipanko
Jan 17 '12 at 8:36
add a comment |
up vote
0
down vote
up vote
0
down vote
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";
}
}
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";
}
}
answered Jan 17 '12 at 8:09
pistipanko
63147
63147
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:30
ds.Tables[0].DefaultView.Sort = "day, hour";
– pistipanko
Jan 17 '12 at 8:36
add a comment |
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:30
ds.Tables[0].DefaultView.Sort = "day, hour";
– pistipanko
Jan 17 '12 at 8:36
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:30
dataGridView1.DataSource = ds.Tables[0];
– user1112847
Jan 17 '12 at 8:30
ds.Tables[0].DefaultView.Sort = "day, hour";
– pistipanko
Jan 17 '12 at 8:36
ds.Tables[0].DefaultView.Sort = "day, hour";
– pistipanko
Jan 17 '12 at 8:36
add a comment |
up vote
0
down vote
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.
add a comment |
up vote
0
down vote
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.
add a comment |
up vote
0
down vote
up vote
0
down vote
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.
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.
answered Jan 11 at 16:21
Casey Crookston
3,00363471
3,00363471
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f8891390%2fhow-to-sort-a-datagridview-by-2-columns%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
i dont think you can sort them both together, you can call your code for 2 columns to order it by day first, and by another column later
– Moonlight
Jan 17 '12 at 8:07
you can have a look here: social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/…
– Adrian Fâciu
Jan 17 '12 at 8:09
Are you using WinForms or something else?
– Anatolii Gabuza
Jan 17 '12 at 8:12
yes, I m using winforms
– user1112847
Jan 17 '12 at 8:14