I am adding a function to keep track of scores for a small game I made.
I want to get the top 5 scores (including name for that score) from a file that contains the scores.
The format of the saved scores is:
[name]-[score]
The scores and names are stored in 2 lists, which I parse this way:
string scores = File.ReadAllText(Environment.GetEnvironmentVariable("TEMP") + "/scores");
string[] splitscores = scores.Split('\n');
foreach (string entry in splitscores)
{
string replace = entry.Replace("[", "").Replace("]", "");
string[] splitentry = replace.Split('-');
if (splitentry.Count() > 1)
{
scorenames.Add(splitentry[0]);
scorelist.Add(Int32.Parse(splitentry[1]));
}
}
Then I retrieve #1 player by using:
int indexMax
= !scorelist.Any() ? -1 :
scorelist
.Select((value, index) => new { Value = value, Index = index })
.Aggregate((a, b) => (a.Value > b.Value) ? a : b)
.Index;
lblhighscore1.Text = "#1: " + scorelist[indexMax] + " by " + scorenames[indexMax];
How can I set the remaining 4 players assuming this is my scorelist:
[broodplank]-[12240]
[flo]-[10944]
[bill]-[11456]
[tony]-[9900]
[benji]-[7562]
I've figured I could do a descending sort of the score list, but that wouldn't cover the changes in the indexes of the usernames list, what is the best approach for this?
Best approach? Don't use parallel collections anti-pattern.
Instead of having 2 lists, create a class that can hold both the name and the score together
class Score
{
public string Name { get; private set; }
public int Score { get; private set; }
public Score(string name, int score)
{
Name = name;
Score = score;
}
}
and have just one list
List<Score> scores = new List<Score>();
foreach (string entry in splitscores)
{
string replace = entry.Replace("[", "").Replace("]", "");
string[] splitentry = replace.Split('-');
if (splitentry.Count() > 1)
{
scores.Add(new Score(splitentry[0], Int32.Parse(splitentry[1]))
}
}
You can easily order by one property and because the whole object will be reordered you'll keep the names in the right order without any additional code:
topScores = scores.OrderByDescending(x => x.Score).Take(5);
In addition to MarcinJuraszeks useful answer, some small things that I came across using his solution which I decided to share.
First problem was with the class which threw me the following error
'Score': member names cannot be the same as their enclosing type
Changing the case of "s" fixed it
class Score
{
public string Name { get; private set; }
public int score { get; private set; }
public Score(string name, int Score)
{
Name = name;
score = Score;
}
}
And calling the individual values can be done with Linq
string numberOne = topScores.Skip(0).First().score
string numberTwo = topScores.Skip(1).First().score
and so on
Related
I'm currently learning C# and have assigned myself to make a program to help me understand OOP which essentially takes in values and assigns them to variables. The program takes in information about football players; the name, last name, position, and shirt number.
I'm trying to use getters and setters to ensure that a shirt number can only be used once. So i've set a list up that stores all the shirt numbers that are being used. The problem i'm having is: the list keeps getting reset and I have no idea why. After one value has been added, by the time the next one gets added, the list is empty again. This makes my if statement in the setter not work as the list does not contain any values.
Im sure this is a rookie error and should be shouting at me, but Im new to this language and am not really sure on all the ins and outs of it.
I haven't really tried much, and I cant find anything online as this seems to be a specific error that im having. I don't know enough about the language to properly troubleshoot this, and what I do know about the language tells me this should work.
namespace RandomObject
{
class Program
{
static void Main(string[] args)
{
Player player1 = new Player("Lucas", "Torreira", "Defensive Midfielder", 11);
Player player2 = new Player("Alexandre", "Lacazette", "Striker", 9);
Player player3 = new Player("Pierre-Emerick", "Aubameyang", "Striker", 14);
Player player4 = new Player();
Console.Write("Please enter new players first name: ");
player4.Name = Console.ReadLine();
Console.Write("Please enter new players last name: ");
player4.LastName = Console.ReadLine();
Console.Write("Please enter new players position: ");
player4.Position = Console.ReadLine();
Console.Write("Please enter new players shirt number: ");
player4.ShirtNo = Convert.ToInt32(Console.ReadLine());
player1.PrintPlayerInfo();
player2.PrintPlayerInfo();
player3.PrintPlayerInfo();
player4.PrintPlayerInfo();
Console.ReadKey();
}
}
}
class Player
{
private List<int> shirtNumbers = new List<int>();
private int _shirtNo;
public void PrintPlayerInfo() //<access modifier> <return type> <method name>(parameters)
{
Console.WriteLine("Player: {0} {1}", Name, LastName);
Console.WriteLine("Position: {0}", Position);
Console.WriteLine("Shirt No.: {0}\n", _shirtNo);
}
public Player()
{
Name = string.Empty;
LastName = string.Empty;
Position = string.Empty;
_shirtNo = 0;
}
public Player(string name, string lastName, string position, int shirtNo)
{
Name = name;
LastName = lastName;
Position = position;
_shirtNo = shirtNo;
AddToList(_shirtNo);
}
private void AddToList(int newNumber)
{
shirtNumbers.Add(newNumber);
Console.WriteLine(shirtNumbers[0]);
}
public string Name { get; set; }
public string LastName { get; set; }
public string Position { get; set; }
public int ShirtNo
{
get { return _shirtNo; }
set
{
if (shirtNumbers.Contains(value) == false)
{
_shirtNo = value;
}
else
{
_shirtNo = 0;
}
}
}
}
}
In my main method I declare 3 instances of the class, with shirt numbers 11, 9, and 14. So when it comes to inputting one into the console using readlines and such, if I were to enter 14, the shirt number should be set to 0. However if I enter 10, it should be set to 10.
The Player class now does two things: it holds information about one player, and it contains a list of shirt numbers for all players. One of those two doesn't belong there.
The private List<int> shirtNumbers = new List<int>(); is an instance variable, meaning each player has its own list of shirt numbers. So if you assign a shirt to player X, the list in player Y's instance has no notion of this, enabling you to assign shirt N to both player X and Y.
Sure, you could fix this by declaring the list to be static, but that's just bad design; the Player class needs to know about one player, not all of them.
So instead keep this shirt number check outside your player class. Declare the shirt list before the player list, and modify your code accordingly.
You should have a static list of numbers. Otherwise every player has its own list of valid numbers.
class Player
{
private static List<int> shirtNumbers = new List<int>();
private int _shirtNo;
}
This way you have a single list that all your player share.
You are using the AddToList method on your constructor to add the shirtlist number which is correctly but when you are defining ShirtNo setter you are not adding to the list
Fix :
public int ShirtNo
{
get { return _shirtNo; }
set
{
if (shirtNumbers.Contains(value) == false)
{
_shirtNo = value;
AddToList(value)
}
else
{
_shirtNo = 0;
}
}
}
i copied your code to debug in my local machine. Few changes that needs to be done to your
1.The shirtNumbers list has to be declared static , if not for every instance of player class will have List (private static List shirtNumbers = new List();)
You are assigning values to the variable directly and not to the property in both the constructors.(getter setter is called property in C#).Hence the if condition inside setter wont be called.
class Player
{
private static List<int> shirtNumbers = new List<int>();
private int _shirtNo;
public void PrintPlayerInfo()
{
Console.WriteLine("Player: {0} {1}", Name, LastName);
Console.WriteLine("Position: {0}", Position);
Console.WriteLine("Shirt No.: {0}\n", _shirtNo);
}
public Player()
{
Name = string.Empty;
LastName = string.Empty;
Position = string.Empty;
ShirtNo = 0;
}
public Player(string name, string lastName, string position, int shirtNo)
{
Name = name;
LastName = lastName;
Position = position;
ShirtNo = shirtNo;
AddToList(_shirtNo);
}
private void AddToList(int newNumber)
{
shirtNumbers.Add(newNumber);
Console.WriteLine(shirtNumbers[0]);
}
public string Name { get; set; }
public string LastName { get; set; }
public string Position { get; set; }
public int ShirtNo
{
get { return _shirtNo; }
set
{
if (shirtNumbers.Contains(value) == false)
{
_shirtNo = value;
}
else
{
_shirtNo = 0;
}
}
}
}
I need sequence numbering for my records display. 50 record for each page.
public List<string[]> InstructionsData(IEnumerable<Assets> InstructionsEntry, int currentUserId)
{
return InstructionsEntry.Select((entry,index) => new string[]
{
(index + 1).ToString(),
entry.state_Id,
entry.batchRef_Id,
entry.assetCategory_Id,
GetAge(entry.age),
entry.assetStatus_Id,
GetStatusTag(entry.recordStatus ??false),
entry.availbaleQty.ToString(),
entry.createdBy,
}).ToList();
The above code which is used for displaying index is working fine. My problem is when I move to next page the index again start from first. Please help me to continue the index number on next page as well.
Simple :
public List<string[]> InstructionsData(IEnumerable<Assets> InstructionsEntry, int currentUserId, int startIndex)
{
return InstructionsEntry.Select((entry,index) => new string[]
{
(startIndex + index + 1).ToString(),
entry.state_Id,
entry.batchRef_Id,
entry.assetCategory_Id,
GetAge(entry.age),
entry.assetStatus_Id,
GetStatusTag(entry.recordStatus ??false),
entry.availbaleQty.ToString(),
entry.createdBy,
}).ToList();
I will not argue about your design choices like
why do you need to return an array of strings instead of structured object?
or why do you need the index when you must have a unique identifier to rely on?
you might have your very peculiar specific reasons behind the scenes, but I'll try to pin point what i might end up doing to retrieve a paginated indexed result set.
First thing first, get a paginated result set of assets (or whatever your use case scenario requires), having some metadata about the given page (current page number, page size, total records)
var paged = data.Page(page: 2, size: 5);
Then on the frontend, or wherever the result is to be displayed, attach the index to returned records (I'll show the C# equivalent, but you will easily achieve the same results in your frontend of choice tech stack)
var indexed = paged.Items
.Select((current, index) =>
{
var skipped = (paged.Page - 1) * paged.Size;
return new
{
Index = skipped + index,
Item = current,
};
});
where the paged result would look like this
public class Paged<T>
{
public IEnumerable<T> Items { get; set; }
public int Page { get; set; }
public int Size { get; set; }
public int Total { get; set; }
}
public class Asset
{
public int Id { get; set; }
public string Name { get; set; }
}
while the actual paging mechanism simply applies Skip and Take
public static class Extensions
{
public static Paged<T> Page<T>(this IEnumerable<T> instance, int? page = 1, int? size = 10)
{
var items = instance
.Skip((page.Value - 1) * size.Value)
.Take(size.Value)
.ToList();
return new Paged<T>()
{
Page = page.Value,
Size = size.Value,
Total = instance.Count() - 1,
Items = items,
};
}
}
check gist for an overview code sample
Situation: I got 3 classes that work with each other.
1: Main (the GUI)
2: Compare (to compare the values)
3: CompareData (inherits the list values)
I want to take two values: a string and a double, and put them in a list. Of course there will be more than just one list item at the end. After the list got filled, I'd like to get the lowest double with it's string and put them in a label.
Here is what I've got so far:
Main:
public class GlobaleDaten //The second List: VglDaten is the one for my situation
{
public static List<Daten> AlleDaten = new List<Daten>();
public static List<Vgl> VglDaten = new List<Vgl>();
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
[...Some Code thats not relevant...]
//addListAb adds values in a ListBox and should also
//place them into the list VglDaten
public void addListAb()
{
listBox.Items.Add(Abzahlungsdarlehenrechner.zgName + " " + "[Abzahlungsdarlehen]" + " " +Abzahlungsdarlehenrechner.zmErg.ToString("0.00") + "€" + " " + Abzahlungsdarlehenrechner.zgErg.ToString("0.00") + "€");
Vgl comp = new Vgl();
comp.name = Abzahlungsdarlehenrechner.zgName;
comp.gErg = Abzahlungsdarlehenrechner.zgErg;
GlobaleDaten.VglDaten.Add(comp);
}
//bVergleich should compare these values from the list
//and show the lowest value in a label
public void bVergleich_Click( object sender, RoutedEventArgs e)
{
if (listBox.Items.Count <= 0)
{
MessageBox.Show("Bitte erst Einträge hinzufügen.");
}
else
{
VglRechner vglr = new VglRechner();
vglr.Compare();
lVergleich.Content = VglRechner.aErg + " " + "€";
}
}
CompareData:
//Only used for storing the values
public class Vgl : Window
{
public string name { get; set; }
public double gErg { get; set; }
}
Compare:
public class VglRechner
{
public static string aName;
public static double aErg;
public void Compare(Vgl comp)
{
//I'm not sure if this is the right way to compare the values
//correct me if I'm wrong please :)
double low = GlobaleDaten.VglDaten.Min(c => comp.gErg);
aErg = low;
aName = comp.name;
}
}
Using Enumerable.Min is the right way to get the lowest value but you won't get the string which belonged to that value in this way, so the Vgl instance.
You could use this approach:
Vgl lowestItem = GlobaleDaten.VglDaten.OrderBy(c => c.gErg).First();
aErg = lowestItem.gErg;
aName = lowestItem.name;
I have a dictionary which stores members of a 'Skiing' tournament. It also stores there scores. What I want to do is be able to find and display the top 3 scores of the members. I was just wondering what the best way would be to approach this as I am stuck at the moment. The following is the dictionary and how a member is added:
public static Dictionary<string, Skier> Skiers = new Dictionary<string, Skier>();
static int income;
string lodgeName;
public SkiLodge(string newLodgeName)
{
newLodgeName = lodgeName;
Skiers = new Dictionary<string, Skier>();
}
static int newNumber = 1;
//ADD SKIER
public Skier AddSkier(string inName, string inAddress, int inScore)
{
string newNumberString = newNumber.ToString();
Skier result = new Skier(newNumberString, inName, inAddress, inScore);
newNumber = newNumber + 1;
Skier S = new Skier(newNumberString, inName, inAddress, inScore);
Skiers.Add(newNumberString, S);
income = income + 100;
return result;
}
I assumed that you have a property in Skier called Score, here how can you achieve your goal.
//Your dictionary must have at least 3 entries.
var orderedTopThree = Skiers.OrderByDescending(s => s.Value.Score).Take(3);
Either of these methods added to your SkiLodge class, will get you what you're looking for.
This will grab your top X KeyValuePairs with the Skier object being the Value property of the KeyValuePair.
public List<KeyValuePair<string,Skier>> GetTopSkiers(int howMany)
{
return Skiers.OrderByDescending(kvp => kvp.Value.Score).Take(howMany).ToList();
}
This will grab your top X Skiers
public List<Skier> GetTopSkiers(int howMany)
{
return Skiers.OrderByDescending(kvp => kvp.Value.Score).Take(howMany).Select(kvp => kvp.Value).ToList();
}
Both methods use the OrderByDescending Linq method, which uses a lambda expression as a selector for the sorting comparison kvp => kvp.Value.Score. Which in this case is saying, foreach kvp (KeyValuePair) in this dictionary, sort them by the Value property, which in this case is the Skier object, and use the Skier object's Score as the value to sort by.
Take will take, up to x values from an Enumerable.
Select then returns an Enumerable resulting from the lambda function passed in. In this case, kvp => kvp.Value returns an Enumerable of Skier objects, instead of a list of the KeyValuePair objects.
Either use a SortedDictionary or enumerate through the keys of dictionary or this code
public class Skier
{
public static Dictionary<string, Skier> Skiers = new Dictionary<string, Skier>();
public int inScore { get; set; }
public Skier()
{
int[] highscore = Skiers.AsEnumerable().OrderByDescending(x => ((Skier)x.Value).inScore).Take(3).Select(y => ((Skier)y).inScore).ToArray();
}
}
You may use LINQ to achieve. Here is one sample query:
Skiers.OrderByDescending(e=>e.Value.inScore).Take(3).ToList();
Using System.Linq, the following code will get you the best 3 Skiers by score:
public List<Skier> GetTop3()
{
var list = Skiers.OrderByDescending(sk=> sk.Value.Score).Take(3).ToList();
return list;
}
I have tried to replicate the behavior and fixed some of the issues in above code. In AddSkier you dont need to create 2 objects.
FetchTopThree() will give you the top 3 results. You can then display the results.
using System.Collections.Generic;
using System.Linq;
public class SkiLodge
{
public static Dictionary<string, Skier> Skiers = new Dictionary<string, Skier>();
static int income;
string lodgeName;
public SkiLodge(string newLodgeName)
{
this.lodgeName = newLodgeName;
}
static int newNumber = 1;
//ADD SKIER
public Skier AddSkier(string inName, string inAddress, int inScore)
{
string newNumberString = newNumber.ToString();
newNumber = newNumber + 1;
Skier skier= new Skier(newNumberString, inName, inAddress, inScore);
Skiers.Add(newNumberString, skier);
income = income + 100;
return skier;
}
public List<Skier> FetchTopThree()
{
return Skiers.Values.OrderByDescending(s => s.InScore).Take(3).ToList();
}
}
public class Skier
{
public string NewNumberString { get; }
public string InName { get; }
private readonly string inAddress;
public int InScore { get; }
public Skier(string newNumberString, string inName, string inAddress, int inScore)
{
this.NewNumberString = newNumberString;
this.InName = inName;
this.inAddress = inAddress;
this.InScore = inScore;
}
}
I would like to do "sorting" under Datagridview ColumnHeaderMouseClick.
Accending or Decending should need to be automatic, selected column value automatic.
I gone through many websites and tried some options but I could not be able to achieve my goal.
private void lst_Install_Item_Main_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
try
{
DataGridViewColumn newColumn = lst_Install_Item_Main.Columns[e.ColumnIndex];
List<test> temp = (List<test>)lst_Install_Item_Main.DataSource;
//var newList = temp.OrderBy(m => m.feet).ToList();
//var newList = temp.AsQueryable().OrderBy(m => m.feet).ToList();
temp.Sort((m1, m2) => m1.feet.CompareTo(m2.feet));
lst_Install_Item_Main.DataSource = temp;
lst_Install_Item_Main.Refresh();
}
catch (Exception ex)
{
MessageBox.Show("There was an error bringing sorting \n" + ex.Message, "Testing", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Above code "sorting" the list on "feet" column but
I would like to pass the columnname which user clicked, is that possible ?
I have input like (1', 21', 123', 5', 10')
Above code sorting the list like >> (1', 10', 123', 21', 5')
But I want output like >> (1', 5', 10', 21', 123')
Is that possible to achieve ?
How to achieve Ascending or Descending here
(I mean while I clicked first time it will do Ascending and while click on same column second time it should need to do Descending)
Your suggestionshelp are greatly appreciated.
If you don't have negative values, then to sort as you want you need either to parse values as numeric or simply pad them:
temp.Sort((m1, m2) => m1.feet.PadLeft(2).CompareTo(m2.feet.PadLeft(2)));
When comparing strings "1", "5" and "10" this will be comparing " 1", " 5" and "10" instead (notice empty space, which is less than 0 character), making them sorted in the right order.
Make sure to chose number big enough to cover padding to the longest number.
You need to sort the values of feet as integers. To do this, you first need to remove the feet-symbol (') and afterwards parse the value to an int (temporarily, the value is still stored as a string).
This should do the trick:
temp.Sort((m1, m2) => int.Parse(m1.feet.Replace("'", "")).CompareTo(int.Parse(m2.feet.Replace("'", ""))));
Also, I would recommend that you don't store the feet-symbol in the value, and instead use some kind of formatting to include it, when showing the values in the Grid. That way you can avoid these kinds of conversions and comparisons, each time you need to use the values.
You have to convert your strings to integer-values as strings are differently ordered (lexicographically 10 comes before 2). Furtheremore as your input contains '-characters you have to delete them first using String.Trim('\'').
temp.Sort((m1, m2) => Convert.ToInt32(m1.feet.Trim('\'')).CompareTo(Convert.ToInt(m2.feet.Trim('\''))));
Alternativly you may also use Linq-OrderBy:
temp = temp.OrderBy(x => Convert.ToInt32(x.feet.Trim('\''))).ToList();
And OrderByDescending if in descending-order.
UPDATED for question # 3, added trigger for sort order
I would suggest you to use ICoparer in such way
public class TestComparer : IComparer<test>
{
bool isAscending;
public TestComparer(bool isAscendingOrder)
{
isAscending = isAscendingOrder;
}
int IComparer<test>.Compare(test a, test b)
{
int c1 = IntFromStr(a.feet);
int c2 = IntFromStr(b.feet);
int res;
res = (c1 > c2) ? 1 : (c1 < c2) ? -1 : 0;
return isAscending ? res : -res;
}
int IntFromStr(string s)
{
int result;
return (int.TryParse(s.Replace("'", ""), out result)) ? result : int.MaxValue;
}
}
this comparer will move not valid items to the end of the sorted list, also you will be able to change your sort behaviour easily, you will call it like below
List < test > lst = new List<test>();
// It will be your property to Trigger value each time you click
// (sortOrderTrigger = !sortOrderTrigger)
bool sortOrderTrigger = true;
lst.Add(new test { feet = "1'" });
lst.Add(new test { feet = "21'" });
lst.Add(new test { feet = "123'" });
lst.Add(new test { feet = "5'" });
lst.Add(new test { feet = "10'" });
lst.Add(new test { feet = "15'" });
lst.Add(new test { feet = "jj'" });
lst.Add(new test { feet = "ff'" });
lst.Sort(new TestComparer(sortOrderTrigger));
Thanks for all your help and Direction.
I have fixed my requirements as like below, Hope this help to someone like me :)
1. Created list which contains the same columns as the columns dataproperty.
public class sortList
{
public string Layer { get; set; }
public string mlenth { get; set; }
public string diameter { get; set; }
public string subtypecd { get; set; }
public string coatingtype { get; set; }
public string year { get; set; }
public string gisid { get; set; }
public string taxdistrict { get; set; }
public string lengthsource { get; set; }
public string shapelen { get; set; }
public string feet { get; set; }
public sortList()
{
this.Layer = ListSortDirection.Ascending.ToString();
this.mlenth = ListSortDirection.Ascending.ToString();
this.feet = ListSortDirection.Ascending.ToString();
this.diameter = ListSortDirection.Ascending.ToString();
this.subtypecd = ListSortDirection.Ascending.ToString();
this.coatingtype = ListSortDirection.Ascending.ToString();
this.year = ListSortDirection.Ascending.ToString();
this.gisid = ListSortDirection.Ascending.ToString();
this.taxdistrict = ListSortDirection.Ascending.ToString();
this.lengthsource = ListSortDirection.Ascending.ToString();
this.shapelen = ListSortDirection.Ascending.ToString();
}
}
2. Written code on ColumnHeaderMouseClick event and order function
private void lst_Install_Item_Main_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
try
{
//Get Column which clicked
DataGridViewColumn newColumn = lst_Install_Item_Main.Columns[e.ColumnIndex];
//Get Values from DataGrid
List<test> temp = (List<test>)lst_Install_Item_Main.DataSource;
//Get the sorting order for that column
string orderby = GetOrder(newColumn.DataPropertyName);
if (orderby == ListSortDirection.Ascending.ToString()) //Ascending
{
if (newColumn.DataPropertyName == "feet") //Feet column sort with double value and required trim
{
temp = temp.OrderBy(x => Convert.ToDouble(x.feet.Trim('\''))).ToList();
}
else if (newColumn.DataPropertyName == "shapelen") //Shapelen column sort with double value and required trim
{
temp = temp.OrderBy(x => Convert.ToDouble(x.shapelen.Trim('\''))).ToList();
}
else ///other columns having string value only.
{
temp = temp.OrderBy(x => x.GetType().GetProperty(newColumn.DataPropertyName).GetValue(x, null)).ToList();
}
}
else // Descending
{
if (newColumn.DataPropertyName == "feet") //Feet column sort with double value and required trim
{
temp = temp.OrderByDescending(x => Convert.ToDouble(x.feet.Trim('\''))).ToList();
}
else if (newColumn.DataPropertyName == "shapelen") //Shapelen column sort with double value and required trim
{
temp = temp.OrderByDescending(x => Convert.ToDouble(x.shapelen.Trim('\''))).ToList();
}
else //other columns having string value only.
{
temp = temp.OrderByDescending(y => y.GetType().GetProperty(newColumn.DataPropertyName).GetValue(y, null)).ToList();
}
}
lst_Install_Item_Main.DataSource = temp;
lst_Install_Item_Main.Refresh();
}
catch (Exception ex)
{
MessageBox.Show("There was an error while sorting \n" + ex.Message, "Closeout Calculator", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private string GetOrder(string columnName)
{
//Store the each coulmn(Ascending/Descending) values to make it dynamic
string ord = sortOrder[0].GetType().GetProperty(columnName).GetValue(sortOrder[0], null).ToString();
if (ord == ListSortDirection.Ascending.ToString())
{
sortOrder[0].GetType().GetProperty(columnName).SetValue(sortOrder[0], ListSortDirection.Descending.ToString(), null);
}
else
{ sortOrder[0].GetType().GetProperty(columnName).SetValue(sortOrder[0], ListSortDirection.Ascending.ToString(), null); }
return ord;
}
3. sortoder list initialize and obj declared at Constructor.
Private List<sortList> sortOrder = new List<sortList>();
sortOrder.Add(new sortList());