My issue is that i have an aspx page which is having try and catch bocks in its code file which will handle exception using exception object in catch,now when the program execution reaches this catch block it calls the public method GetExceptionDetails which will return a long string text containing the values of all the properties of exception but not property's name in it.Now when i insert the properties values into table object's field of database everything is right upto the point when the code reaches at db.submitchanges(),in which an exception statement pops out which reads sqldatetimeoverflow and under sqltypesexception.Please help me figure out the issue in this,Below is the whole code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication5
{
public partial class EnterMarks : System.Web.UI.Page
{
public float average,total;
public string grade,chk,exmessage;
DataClasses1DataContext db = new DataClasses1DataContext();
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["StudentID"] != null)
{
Label1.Text = Request.QueryString["StudentID"];
}
}
protected void Button1_Click(object sender, EventArgs e)
{
List<int> stdID = new List<int>();
tblGrade tb = new tblGrade();
total = (float)(Convert.ToDouble(TextBox1.Text) + Convert.ToDouble(TextBox2.Text) + Convert.ToDouble(TextBox3.Text));
average = total / 3;
if (average > 85 && average < 90)
{
grade = "AA";
}
else if(average>80 && average<85)
{
grade = "A";
}
else if (average > 75 && average < 80)
{
grade = "BB";
}
else if (average > 70 && average < 75)
{
grade = "B";
}
else if (average > 65 && average < 70)
{
grade = "C";
}
else if (average > 60 && average < 65)
{
grade = "CC";
}
else if (average > 55 && average < 60)
{
grade = "D";
}
else
{
grade = "DD";
}
//var query = from m in db.tblGrades
// where m.StudentID == Convert.ToInt32(Request.QueryString["StudentID"])
// select m;
// foreach (var q in query)
//{
tb.StudentID = Convert.ToInt32(Request.QueryString["StudentID"]);
tb.Grade = grade;
db.tblGrades.InsertOnSubmit(tb);
db.SubmitChanges();
Response.Redirect("WebForm1.aspx");
}
protected void Button2_Click(object sender, EventArgs e)
{
//var query1 = from n in db.tblContacts where n.StudentID == int.Parse(TextBox4.Text) select n;
tblExcDet te = new tblExcDet();
var query1 = from n in db.tblContacts select n.StudentID;
//try
//{
foreach (var q in query1)
{
if (q.Equals((int.Parse(TextBox4.Text))))
{
Label2.Text = "ID Found";
}
}
try
{
int? i = null;
tblContact tc = new tblContact();
tc.StudentID = (int)i ;
//db.tblContacts.InsertOnSubmit(tc);
db.SubmitChanges();
}
catch (Exception ex)
{
exmessage = GetExceptionDetails(ex);
te.ExMessage = exmessage.Split('*')[0];
te.ExData = exmessage.Split('*')[1];
te.ExInner = exmessage.Split('*')[2];
te.ExTargetSite = exmessage.Split('*')[3];
te.ExStackTrace = exmessage.Split('*')[4];
te.ExHelplink = exmessage.Split('*')[5];
te.ExSource = exmessage.Split('*')[6];
te.ExHresult = exmessage.Split('*')[7];
db.tblExcDets.InsertOnSubmit(te);
db.SubmitChanges();
Label2.Text = "Can't assign null value into a table id";
}
}
//public static string GetExceptionDetails(Exception ex)
//{
// var properties = ex.GetType().GetProperties();
// var fields = properties.Select(property=>new{
// name = property.Name,value = property.GetValue(ex,null)
// }).Select(x => String.Format(
// "{0} = {1}",
// x.name,
// x.value != null ? x.value.ToString() : String.Empty
// ));
// return String.Join("*", fields);
//}
public static string GetExceptionDetails(Exception ex)
{
var properties = ex.GetType().GetProperties();
var fields = properties.Select(property => new
{
name = property.Name,
value = property.GetValue(ex, null)
}).Select(x => String.Format(
"{0}",
x.value != null ? x.value.ToString() : String.Empty
));
return String.Join("*", fields);
}
}
}
Also here i'm using LINQ structure to insert data into sql server database.
Do you have the field set as autogenerated in the designer? If that's not the problem, I'd suggest setting up logging of the data context actions to the console and checking the actual SQL generated to make sure that it's inserting that column, then trace backward to find the problem.
context.Log = Console.Out;
FWIW, I often set my "CreatedTime" and "LastUpdatedTime" columns up as autogenerated (and readonly) in the designer and give them a suitable default or use a DB trigger to set the value on insert or update. When you set it up as autogenerated, it won't include it in the insert/update even if modified. If the column doesn't allow nulls, then you need to supply an alternate means of setting the value, thus the default constraint and/or trigger.
You might also want to try an explicit cast to
SqlDbType.DateTime
before doing updatechanges
Related
Hey guys I'm currently working on a bank program for a class project. The idea the user will need to make an account if not done so already but if they already do they can just login using account number and pin. However. instead of my program constantly adding data to an array that's size is 100 it just replaces the data in slot [0] just wondering why.
public partial class Form1 : MetroForm
{
//For Creating new account
string newAccountType;
Accounts[] customers = new Accounts[99999];
int temp;
string VerifyPin = ("");
private void openAccount_Click(object sender, EventArgs e)
{
for (int index=0;index < customers.Length; ++index)
{
var R1 = new Random();
var R2 = new Random();
customers[index] = new Accounts();
customers[index].Name = newName.Text;
customers[index].accountType = newAccountType;
customers[index].accountNumber = (R1.Next(1000000,9000000))+(R2.Next(100,9000));
customers[index].accountPin = createPin.Text;
customers[index].accountBalance = 100.00;
temp = index;
}
MetroMessageBox.Show(this, "Thank you member "+customers[temp].Name+"\nYour member number is: "+customers[temp].accountNumber, "You are now a memeber", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
metroTabControl1.SelectedTab = metroTabPage2;
}
private void checkBalance_Click(object sender, EventArgs e)
{
int veri=0;
bool isfound = false;
for (int count = 0; count < customers.Length; ++count)
{
if (Convert.ToInt32(userName.Text) == customers[count].accountNumber)
{
veri = count;
isfound = true;
}
else
isfound = false;
accountnotfound.Text = "Account Not Found";
}
if (isfound && (customers[veri].accountPin == pinText.Text))
{
MetroMessageBox.Show(this, "account found", "account found");
}
else
{
MetroMessageBox.Show(this, "account not found or wrong pin", "account not found");
pinText.Text = "";
}
accountBalance.Visible = true;
userWithdraw.Visible = true;
userDeposite.Visible = true;
accountBalance.Text = "Welcome, "+customers[veri].Name+"\nYour current balance is: "+customers[veri].accountBalance;
}
public class Accounts
{
private string name, AccountType, AccountPin;
private int AccountNumber;
private double AccountBalance;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int accountNumber
{
get
{
return AccountNumber;
}
set
{
AccountNumber = value;
}
}
public string accountPin
{
get
{
return AccountPin;
}
set
{
AccountPin = value;
}
}
public string accountType
{
get
{
return AccountType;
}
set
{
AccountType = value;
}
}
public double accountBalance
{
get
{
return AccountBalance;
}
set
{
AccountBalance = value;
}
}
}
I think you just need to keep track of which element in the array is available (i.e. has a null value). Once no elements in the array are null, this means that the customers array is full, so you can't add any more customers at that point.
Make these following changes. In the part of the code just where the code starts the loop:
bool added = false;
for (int index=0;index < customers.Length; ++index)
{
if (customers[index] != null) continue;
...
Also, after you actually add a customer, do this (right after the loop ends):
if (!added)
{
// show error message here!
}
else
{
MetroMessageBox.Show(this, "Thank you member "+customers[temp].Name+"\nYour member number is: "+customers[temp].accountNumber, "You are now a memeber", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);
metroTabControl1.SelectedTab = metroTabPage2;
}
for (int index=0;index < customers.Length; ++index)
customers[index] = new Accounts();
Index will be 0 every time your array loops, thus replacing customers[0] every time you openAccount_Click is called.
You don't really need to loop to add. You just need to make sure you are writing the next possible index. Maybe use your Temp variable and increment it + 1 for every user added and then without a loop do like do.
customers[Temp] = new Accounts();
customers[Temp].Name = newName.Text;
customers[Temp].accountType = newAccountType;
customers[Temp].accountNumber = (R1.Next(1000000,9000000))+ (R2.Next(100,9000));
customers[Temp].accountPin = createPin.Text;
customers[Temp].accountBalance = 100.00;
Temp += 1;
You would be better off using a List of Accounts for your customers global instead.
List<Accounts> customers = new List<Accounts>();
Then inside openAccount_Click you can add a new Accounts like so.
customers.Add(new Accounts {
Name = newName.Text,
accountType = newAccountType,
accountNumber = (R1.Next(1000000,9000000))+(R2.Next(100,9000)),
accountPin = createPin.Text,
accountBalance = 100.00
});
bool added = false;
for (int x = 0; x <= temp; x++)
{
if (customers[temp] != null) continue;
{
for (int indexies = 0; indexies < customers.Length; indexies++)
{
var R1 = new Random();
var R2 = new Random();
Convert.ToInt32(createPin.Text);
customers[temp] = new Accounts();
customers[temp].Name = newName.Text;
customers[temp].accountType = newAccountType;
customers[temp].accountNumber = 1;//(R1.Next(1000000, 9000000)) + (R2.Next(100, 9000));
customers[temp].accountPin = Convert.ToInt32(createPin.Text);
customers[temp].accountBalance = 100.00;
added = true;
}
}
}
I'm working with Google Adwords and currently can't get specific info. On my Adwords account I set 'IP address exclusion' with 3 IPs. I want to get this IPs from my code:
AdWordsUser user = new AdWordsUser();
var campaignService = (CampaignCriterionService)user.GetService(AdWordsService.v201506.CampaignCriterionService);
int offset = 0;
int pageSize = 500;
var page = new CampaignCriterionPage();
String awql = "SELECT Id where IsNegative = true ORDER BY Id ASC LIMIT " + offset + "," + pageSize;
try
{
do
{
page = campaignService.query(awql);
// Display the results.
if (page != null && page.entries != null)
{
int i = offset;
foreach (var item in page.entries)
{
var t = item; //my work logic here ....
i++;
}
}
offset += pageSize;
} while (offset < page.totalNumEntries);
Debug.WriteLine("Number of items found: {0}", page.totalNumEntries);
}
catch (Exception e)
{
throw new System.ApplicationException("Failed to retrieve campaigns", e);
}
Query returns number of resuls: 3, but without actual info about ipAddress( ipAddress contains null) .
what can I do?
Unfortunately I do not believe that AWQL provides a selector for the Address of a blocked IP. In any case, it is certainly NOT supplied with the AWQL statement you have used above which is only bringing back the Id field:
String awql = "SELECT Id where IsNegative = true ORDER BY Id ASC LIMIT " + offset + "," + pageSize; try
This is why the value is null in your response.
The only way I believe it is possible is to get your hands dirty with the Selector and Predicate objects for that service and use the get() method rather than the query() one.
This solution works for me (admittedly with a later version of the API)
var campaignCriterionService = (CampaignCriterionService)user.GetService(AdWordsService.v201601.CampaignCriterionService);
int offset = 0;
int pageSize = 500;
var page = new CampaignCriterionPage();
try
{
do
{
page = campaignCriterionService.get(new Selector
{
fields = new string[] { IpBlock.Fields.Id, IpBlock.Fields.IpAddress },
predicates = new Predicate[]
{
new Predicate
{
field = IpBlock.Fields.CriteriaType,
#operator = PredicateOperator.EQUALS,
values = new string[] { "IP_BLOCK" }
}
}
});
// Display the results.
if (page != null && page.entries != null)
{
int i = offset;
foreach (var item in page.entries)
{
var t = item; //my work logic here ....
i++;
}
}
offset += pageSize;
} while (offset < page.totalNumEntries);
Debug.WriteLine("Number of items found: {0}", page.totalNumEntries);
}
catch (Exception e)
{
throw new System.ApplicationException("Failed to retrieve campaigns", e);
}
I tried running my program, and have also compared my code to my friend's code, but the error keeps on showing up even though we tried changing these lines (which I think where the error is coming from):
try
{
FileStream b = new FileStream(#"C:\User\User_2\Desktop\board.txt", FileMode.Open);
StreamReader stream = new StreamReader(b);
int x = 0;
while (!stream.EndOfStream)
{
if (x == 0)
g1 = stream.ReadLine().Split(' ');
else if (x == 1)
g2 = stream.ReadLine().Split(' ');
else if (x == 2)
g3 = stream.ReadLine().Split(' ');
x++;
}
stream.Close();
b.Close();
}
catch (Exception e) { }
The program is used to check for a text file which contains these 3 lines:
O . X
X O .
X . O
...and see if there is a winner.
This is the part where Visual Studio highlights the error:
int n = 0;
int m = n + 1;
int o = m + 1;
Boolean result = false;
int winner = 0;
string dw = "";
while (n <= 2)
{
// In this if-statement is the error:
if (g1[n].Equals(g2[n]) && g2[n].Equals(g3[n]) && !g1[n].Equals("."))
{
result = true;
winner++;
dw = g1[n];
}
if (g1[n].Equals(g1[m]) && g1[m].Equals(g1[o]) && !g1[n].Equals("."))
{
result = true;
winner++;
dw = g1[n];
}
else if (g2[n].Equals(g2[m]) && g2[m].Equals(g2[o]) && !g2[n].Equals("."))
{
result = true;
winner++;
dw = g2[n];
}
else if (g3[n].Equals(g3[m]) && g3[m].Equals(g3[o]) && !g3[n].Equals("."))
{
result = true;
winner++;
dw = g3[n];
}
else if (g1[n].Equals(g2[m]) && g2[m].Equals(g3[o]) && !g1[n].Equals("."))
{
result = true;
winner++;
dw = g1[n];
}
else if (g3[n].Equals(g2[m]) && g2[m].Equals(g1[o]) && !g3[n].Equals("."))
{
result = true;
winner++;
dw = g3[n];
}
n++;
}
I really don't know what to do know, I can't make it work.
EDIT: I tried printing out the values of the arrays before the if statements but it doesn't print anything out. Sorry guys, I'm really new here.
First of all, try reading the file like this:
using System.IO;
try
{
var file = #"C:\User\User_2\Desktop\board.txt";
var lines = File.ReadAllLines(file).ToList();
var g1 = lines[0].Split(' ');
var g2 = lines[1].Split(' ');
var g3 = lines[2].Split(' ');
}
catch (Exception e)
{
throw e;
}
Probably now you'll get an exception thrown.
The line catch (Exception e) { } is the culprit for not being notified that there is an exception. You should always handle the exceptions that you catch in your code.
P.S. Probably you have to use C:\Users\... in the path, instead of C:\User\.... Anyway, make sure that you use a valid path to your file.
When using Equals you must ensure the object you are calling is not null;
object oneValue = 1;
object nullValue = null;
var result = nullValue.Equals(oneValue); // Throws NullReferenceException because nullValue is null
You could use the equality operator instead.
string oneValue = "1";
string nullValue = null;
var result = nullValue == oneValue; // False
You can use the == operator instead of the Equals method, which needs the object to be instantiated. But then you still need to make sure the value isn't null.
I searched for the solutions in some of the questions that resembles this problem, but couldn solve it, so kindly provide a clear idea about how to solve this.
Order orderDetails= createOrder();
long voucherId = (long)orderDetails.Vouchers.FirstOrDefault().Number; // exception here..
and the createOrder function returns the orderDetails of type Order.
Vouchers is my voucher table,
Number is a column's name in the voucher table.
I have no idea, why how to solve this exception. Any idea about it ?
PART I :
*EDIT:*
private Order createOrder()
{
IList<OfferInfo> offerInformation = new List<OfferInfo>();
OfferInfo offer = new OfferInfo()
{
OfferId = 2,
Message = "test msg",
CreatedDate = System.DateTime.Now,
Gender = "male",
ReceiverName = "john",
ReceiverEmail = "ebenezar#gmail.com"
};
offerInformation.Add(offer);
Order order = new Order();
order.Id = 721;
order.Amount = 1000;
order.CreatedDate = System.DateTime.Now;
order.User = userDetails;
return BLOrder.CreateOrder(order, offerInformation);
}
NOTE:
It inturns call the CreateOrder from the BLOrder which returns the retrieved data in Order type. ( if var is of Order type and is returned, it will have something like, var.xxx="some value" , var.yyy="some value"..)
PART II:
public static Order CreateOrder(Order order, IList<OfferInfo> offerList)
{
order = CreateNewOrder(order, offerList);
Intreat.MSMQ.MSMQHelper.AddOffers(order, offerList);
return order;
}
private static Order CreateNewOrder(Order order, IList<OfferInfo> offerList, bool updateUser = true)
{
try
{
if (updateUser)
{
VerifyUserDetails(order.User);
senderUserId = BLUser.UpdateUser(order.User);
order.User = null;
Logger.WriteLog("Sender user added/updated successfully. UserID:" + senderUserId.ToString());
}
else
senderUserId = order.UserId;
if (order.Company != null)
order.CompanyId = BLCompany.UpdateCompany(order.Company).Id;
VerifyOrderDetails(order, offerList);
using (IntreatEntities intreat = new IntreatEntities())
{
foreach (OfferInfo offer in offerList)
{
orderAmt = (double)((from po in intreat.PartnerOffers
where po.Id == offer.OfferId
select po.Price * offer.Quantity).ToList()).Sum();
order.Amount += orderAmt;
if (offer.IsPos)
tableOrderAmt += orderAmt;
}
if ((tableOrderAmt > 0) && (order.TipPercentage != null) && (order.TipPercentage.Value) > 0)
{
double tipAmt = (tableOrderAmt * (order.TipPercentage.Value * .01));
order.TipAmount = Math.Round(tipAmt);
order.Amount = (double)(order.Amount + order.TipAmount);
}
order.CreatedDate = DateTime.Now;
order.UserId = (Guid)senderUserId;
Logger.WriteLog(string.Format(CultureInfo.InvariantCulture, "order.TableNumber:{0}", order.TableNumber == null ? "(empty)" : order.TableNumber.ToString()));
intreat.Orders.AddObject(order);
intreat.SaveChanges();
Logger.WriteLog("Order added successfully. OrderId:" + order.Id.ToString(CultureInfo.InvariantCulture));
}
return order;
}
catch (Exception ex)
{
Logger.WriteLog(ex);
throw;
}
}
incorporate this line of code order.Vouchers.Load(); as done below and try
private static Order CreateNewOrder(Order order, IList<OfferInfo> offerList, bool updateUser = true)
{
try
{
Guid? senderUserId = null;
/// Process user first so that, the user details are stored even if there is any error in other areas
///
if (updateUser)
{
VerifyUserDetails(order.User);
/// Create/update sending user.
///
senderUserId = BLUser.UpdateUser(order.User);
order.User = null;
Logger.WriteLog("Sender user added/updated successfully. UserID:" + senderUserId.ToString());
}
else
senderUserId = order.UserId;
/// Add company details before processing the order, so that the company details are stored if there is any error in other areas.
///
if (order.Company != null)
order.CompanyId = BLCompany.UpdateCompany(order.Company).Id;
/// Verify and process order
///
VerifyOrderDetails(order, offerList);
using (IntreatEntities intreat = new IntreatEntities())
{
/// Find total amount for the order
double orderAmt = 0;
double tableOrderAmt = 0;
order.Amount = 0;
foreach (OfferInfo offer in offerList)
{
orderAmt = (double)((from po in intreat.PartnerOffers
where po.Id == offer.OfferId
select po.Price * offer.Quantity).ToList()).Sum();
order.Amount += orderAmt;
//If isPos, consider for tip calculation
if (offer.IsPos)
tableOrderAmt += orderAmt;
}
//check if tip amount has to be calculated, by checking for the tableorderAmt
if ((tableOrderAmt > 0) && (order.TipPercentage != null) && (order.TipPercentage.Value) > 0)
{
double tipAmt = (tableOrderAmt * (order.TipPercentage.Value * .01));
order.TipAmount = Math.Round(tipAmt);
order.Amount = (double)(order.Amount + order.TipAmount);
}
order.CreatedDate = DateTime.Now;
order.UserId = (Guid)senderUserId;
Logger.WriteLog(string.Format(CultureInfo.InvariantCulture, "order.TableNumber:{0}", order.TableNumber == null ? "(empty)" : order.TableNumber.ToString()));
/// Create and save order in db
///
intreat.Orders.AddObject(order);
intreat.SaveChanges();
order.Vouchers.Load();
Logger.WriteLog("Order added successfully. OrderId:" + order.Id.ToString(CultureInfo.InvariantCulture));
}
return order;
}
catch (Exception ex)
{
Logger.WriteLog(ex);
throw;
}
}
I have a datagridview that I would like to have rows sorted based on the portion of a string entered from a user. The entered string is compared with all of the strings in a particular column. For instance, if I gave "comp" as the search word, the program would try to compare the search word with the strings on first column and sort the rows in a descending order which starts with "comp", such as "compare", "composition", "computer" etc. Rest of the words that do not match is either left alone or sorted in an alphabetical order (whichever is easier).
In LINQ, I am aware that you can apply the following code to achieve what you wanted with a string array:
var sortedWords = words.Where(x => x.Contains("comp"))
.OrderByDescending(x => x);
How can I achieve the same thing in Datagridview as I need to have the rows sorted, not just the items inside a particular column?
Edit:
The following code is giving a System.InvalidOperationException. (SetCurrentCellAddressCore is being called twice)
private void DGVPointCtrl_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
MatchComparer mc = new MatchComparer();
DGVPointCtrl.Sort(mc); //Error
}
I'm probably doing something wrong but I'm not sure why. Here is the code that programatically adds the rows for testing purposes:
private void BtnRefresh_Click(object sender, EventArgs e)
{
try
{
DGVPointCtrl.Rows.Clear();
int mainIndex = CmbMainDevice.SelectedIndex;
int subIndex = CmbSubDevice.SelectedIndex;
DDCDAO ddcdao = new DDCDAO(DDCGlobal.ddcEngineIP, ddc.Ip);
string pointListType;
object rs;
//Currently only supports IO DDC Request
//TO DO: Change DDCDAO to send proper subdevice requests
if (mainIndex == 0) //IO
{
#region Main Device: IO
}
//First row is for searching items
DGVPointCtrl.Rows.Add(new DataGridViewRow());
for (int i = 1; i < 5; i++)
{
DGVPointCtrl.Rows.Add(new DataGridViewRow());
DGVPointCtrl.Rows[i].ReadOnly = true;
}
DGVPointCtrl.Columns[0].SortMode = DataGridViewColumnSortMode.Programmatic;
DGVPointCtrl.Rows[0].DefaultCellStyle.Font =
new Font(DGVPointCtrl.DefaultCellStyle.Font, FontStyle.Italic | FontStyle.Bold);
if (subIndex == 1) //BI
{
PointDGVColumnGenerate("IO_BI");
}
else if (subIndex == 2) //BO
{
PointDGVColumnGenerate("IO_BO");
}
else if (subIndex == 3) //AI
{
PointDGVColumnGenerate("IO_AI");
}
else if (subIndex == 4) //AO
{
PointDGVColumnGenerate("IO_AO");
}
DGVPointCtrl.Rows[1].Cells[0].Value = "IO12314";
DGVPointCtrl.Rows[2].Cells[0].Value = "IO21948";
DGVPointCtrl.Rows[3].Cells[0].Value = "IO28194";
DGVPointCtrl.Rows[4].Cells[0].Value = "VP12984";
DGVPointCtrl.Rows[2].Cells[1].Value = "asdf";
#endregion
}
catch
{
}
}
private void PointDGVColumnGenerate(string key)
{
int colCount = 0;
DGVColumnTable.Clear();
for (int i = 0; i < COL_MAX; i++)
{
DGVPointCtrl.Columns[i].HeaderText = " ";
DGVPointCtrl.Columns[i].Visible = true;
}
foreach (string s in UIConstant.DDCPCtrlListColumnText[key])
{
DGVPointCtrl.Columns[colCount].HeaderText = s;
DGVColumnTable.Add(DGVPointCtrl.Columns[colCount]);
colCount++;
}
}
Edit2:
public class MatchComparer : IComparer
{
private static IComparer defaultComparer = new CaseInsensitiveComparer();
int IComparer.Compare(object x, object y)
{
DataGridViewRow xr = (DataGridViewRow)x;
DataGridViewRow yr = (DataGridViewRow)y;
string xs = "";
string ys = "";
try
{
xs = xr.Cells[0].Value.ToString();
}
catch
{
}
try
{
ys = yr.Cells[0].Value.ToString();
}
catch
{
}
if (HasMatch(xs) && !HasMatch(ys)) return -1;
else if (!HasMatch(xs) && HasMatch(ys)) return 1;
else return defaultComparer.Compare(xs, ys);
}
This is possible only if you are populating the grid yourself as opposed to binding it to the database.
Set DataGridViewColumn.SortMode to Programmatic.
Use DataGridView.Sort to impose a comparer like this:
public class MatchComparer : IComparer {
int IComparer.Compare(object x, object y) {
if (HasMatch(x) && !HasMatch(y)) return -1;
else if (!HasMatch(x) && HasMatch(y)) return 1;
else return defaultComparer.Compare(x, y);
}
private bool HasMatch(object x) {
return x is string && ((string)x).StartsWith("comp");
}
private static IComparer defaultComparer = new CaseInsensitiveComparer();
}