blah blah blah is here! blah blah » Close

up0down
link

My dataGridView is fetching data from an xml file, the AutoRefresh option will reload the data after an interval of 1 minute.

Let's assume that the user had "Checked" the AutoRefresh checkBox and had minimised the WinForm.....

Is it possible that I can "restore" my winForm as soon as the dataGridView gets updated with new data (Autorefresh)????

last answered one year ago

6 answers

up0down
link

To restore a minimized form, you can use this code:

if (this.WindowState == FormWindowState.Minimized)
{
this.WindowState = FormWindowState.Normal;
}

gsvirdi
412

what I was not able to figure out was: How can I find out that the DataGridView had got new data? How to know when the dataGridView is updated with new row or updated cells?

up0down
link

I might not have used the best practise.... but this worked!!!!

I did something like this:

// On form load I did
int Count, RowX, RowY = 1;
Count++;
// To fetch the 1st count of Rows.
if (Count < 2)
RowX = dataGridView1.RowCount;

// after the form is re-loaded.....
Form1_Load(this, EventArgs.Empty);
// this will get the later counts of Rows after every refresh of data
RowY = dataGridView1.RowCount;
if (RowY != RowX)
this.WindowState = FormWindowState.Normal;


I need another help...... How can I sort multiple columns in the dataGridView????
Sort first on "Date" then sort second on "Time" ?????

PS: I'm using xml as the dataSource for this dataGridView.

vulpes
17279

If you want to sort the DGV on multiple columns then you'll have to write your own IComparer and pass an instance of it to the Sort() method. If you're recoiling in horror, this isn't as difficult as it sounds - see http://msdn.microsoft.com/en-us/library/wstxtkxs(VS.90).aspx for an example using a couple of string columns. If both your columns contain DateTime values, then you'll need to use the DateTime.Compare rather than the String.Compare method.

up0down
link

I tried something like this:

// Reading / Displaying xml in dataGridView1.
DataSet ds = new DataSet();
ds.ReadXml(filename);
dataGridView1.DataSource = ds;
dataGridView1.DataMember = "news";
dataGridView1.AutoResizeColumns();


And as per ur previous comment I added this line in Form1_Load
dataGridView1.Sort(new RowComparer(SortOrder.Descending));


I'd also added the new class added for sorting multiple columns
private class RowComparer : System.Collections.IComparer
{
private static int sortOrderModifier = 1;

public RowComparer(SortOrder sortOrder)
{
sortOrderModifier = -1;
}

public int Compare(object x, object y)
{
DataGridViewRow dataGridViewRow1 = (DataGridViewRow)x;
DataGridViewRow dataGridViewRow2 = (DataGridViewRow)y;

// Try to sort based on the Date column.
int CompareResult = System.String.Compare(
dataGridViewRow1.Cells[0].Value.ToString(),
dataGridViewRow2.Cells[0].Value.ToString());

// If the Dates are equal, sort based on the Time.
if (CompareResult == 0)
{
CompareResult = System.String.Compare(
dataGridViewRow1.Cells[1].Value.ToString(),
dataGridViewRow2.Cells[1].Value.ToString());
}
return CompareResult * sortOrderModifier;
}
}


But it's giving an exception "DataGridView is data-bound. The control can not use the comparer to perform the the sort operation".

Guidance please..........

vulpes
17279

This method only works if you populate the DGV manually. If you're using databinding (i.e. setting the DataSource property) then you have to sort the data using an IComparer or other approach BEFORE you bind it to the DGV. Also, unless dates are displayed in yyyy/MM/dd format, your RowComparer won't work as it stands because you're sorting DateTime values, not their string representations.

gsvirdi
412

Ohhh..... and u were saying "If you're recoiling in horror, this isn't as difficult as it sounds".

gsvirdi
412

But the default format is System.String.Compare(string A, string B), so I didn't changed anything there.

up0down
link

I just thought of an easy way to do this without writing your own IComparer.

If the first two columns are named "date" and "time", then try the following:

DataSet ds = new DataSet();
ds.ReadXml(filename);
DataTable dt = ds.Tables["news"];
DataView dv = dt.DefaultView;
dv.Sort = "date, time";
DataTable dt2 = dv.ToTable();
dataGridView1.DataSource = dt2;
dataGridView1.AutoResizeColumns();


EDIT - see comments below

The only way I can think of doing this is to create an extra 'DateTime' column in the DataTable which combines the 'Date' and 'Time' columns, sort on that and then hide it in the DGV.

An advantage of this approach is that we can then use another overload of the DGV's Sort() method which sorts on a single column and can still be used even if the DGV is databound.
DataSet ds = new DataSet();
ds.ReadXml(filename);
DataTable dt = ds.Tables["news"];
DataColumn dc = new DataColumn("DateTime", typeof(DateTime));
dt.Columns.Add(dc);
string format = "dd MMM yyyy HH-mm";

for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow dr = dt.Rows[i];
string s = dr["Date"].ToString().Trim() + " " + dr["Time"].ToString().Trim();
DateTime temp;
DateTime.TryParseExact(s, format, null, 0, out temp);
dr["DateTime"] = temp;
}

dataGridView1.DataSource = ds;
dataGridView1.DataMember = "news";
DataGridViewColumn dgvc = dataGridView1.Columns["DateTime"];
dataGridView1.Sort(dgvc, ListSortDirection.Ascending); // or Descending ?
dgvc.Visible = false;
dataGridView1.AutoResizeColumns();

// code to highlight rows if date is today
foreach(DataGridViewRow row in dataGridView1.Rows)
{
if (row.IsNewRow) break;
if (((DateTime)row.Cells["DateTime"].Value).Date == DateTime.Today)
{
row.DefaultCellStyle.BackColor = Color.Red; // or whatever
}
}

gsvirdi
412

this is not sorting..... my xml is something like this: <?xml version="1.0" encoding="utf-8" ?> <CNI> <news> <Date>05 Apr 2010</Date> <Time>16-06</Time> <News>Just tried to create this thing.</News> </news> <news> <Date>06 Apr 2010</Date> <Time>10-36</Time> <News>Just an entry to test.</News> </news> </CNI>

vulpes
17279

The problem is that the XML file doesn't contain schema info and so the Date and Time nodes are inferred to be of type string rather than DateTime. Consequently, the DataView isn't sorted properly. I haven't time right now but I'll see if I can come up with something and get back to you later.

gsvirdi
412

No problem at all, take ur time. Let's assume that I'm still using my previous code to fetch xml file and fill the DataSet. if u can just tell me "how can I get the value of the 1st cell in all rows of the dataGridView??? I'm planning to change the background color of that row who's date (1st cell) is today.

vulpes
17279

Please see my edit.

gsvirdi
412

That's WONDERFUL..... But Sorting is not only the case, a user will be updating these xml news file. And u know that when somebody else needs to do some work.... they want it to be Simplest and minimum. So I was trying to keep the interface & Input requirement to the minimum. Fo input purpose I was thinking that we can do something like this: <news> <Date_Time>06-5-2010, 10:36</Date_Time> <News>Just an entry to test.</News> </news>. I was thinking that it would be possible to programmatically input the current date & time in 24Hr format. Any better way u suggest????

vulpes
17279

Even if you did that, it would still be inferred to be a string rather than a DatetTme and so you'd again have to create a separate DateTime column for sorting purposes. As far as I can see, the only way you can infer it to be a DateTime is to include the schema in the xml file and (worse) express all DateTimes in ISO 8601 format which is not very friendly.

gsvirdi
412

This is sad.... Can't we sort strings to make life easier.... ??

gsvirdi
412

How can I get the Row count of this dataGridView in Interger?????

vulpes
17279

You can only sort on strings if you don't mind expressing the date in a format which has the year first such as yyyy-MM-dd HH:mm.

vulpes
17279

The Row count can be found from the expression dataGridView1.Rows.Count. However, if you're allowing the user to add new rows, then this expression will include the new empty row so you need to be careful to exclude that (as I did above) when iterating through the rows.

up0down
link

Thx for the help....... Plz ignore that previous comment (comparing columns).

Somehow I'm again not able to add comments

I've made a small change in xml file to make a HUGE impact.

Previous xml file
<CNI>
<news>
<Date>05 Apr 2010</Date>
<Time>16-06</Time>
<News>Just tried to create this thing.</News>
</news>
<news>
<Date>06 Apr 2010</Date>
<Time>10-36</Time>
<News>Just an entry to test.</News>
</news>
</CNI>


New xml file.....
<CNI>
<Apr>
<Date>05 Apr 2010</Date>
<Time>16-06</Time>
<News>Just tried to create this thing.</News>
</Apr>
<May>
<Date>17 May 2010</Date>
<Time>10-36</Time>
<News>Just an entry to test.</News>
</May>
</CNI>


In previous code we were using
DataTable dt = ds.Tables["news"];
dataGridView1.DataMember = "news";
and in this new xml I've used

DataTable dt = ds.Tables[monthtoday];
dataGridView1.DataMember = monthtoday;
so that news (only) of this month are fetched.

I'm having a doubt that in present scenario if I want to fetch "ALL" news.... then how should I go ahead with that?

vulpes
17279

You can only bind the DGV to one DataTable at a time. If you wanted to have a separate DataTable for each month, then you'd need a ListBox (say), listing the months, and the DGV would then display the entries for the currently selected month. If you wanted to display ALL months at once, then you'd need to create a separate DataTable programatically which merged all the others and then bind to that.

gsvirdi
412

I'm trying to write back the DGV into the xml but I'm not able to do so...... Where am I making the mistake?????? DataSet ds = new DataSet(); this.dataGridView1.Visible = true; this.dataGridView1.Columns.Remove("DateTime"); ds=(DataSet)(dataGridView1.DataSource); DateTime column is added in the last but it remains in the xml file.....

up0down
link

You need to delete the extra column from the dataset, not from the DGV.

Also, unless you're rewriting to the file just before the application closes, then I'd copy the dataset first, remembering that the DGV is still bound to the original one.

DataSet ds = (DataSet)dataGridView1.DataSource;
DataSet copyDs = ds.Copy();
DataColumn dc = copyDs.Tables["news"].Columns["DateTime"];
copyDs.Tables["news"].Columns.Remove(dc);
copyDs.WriteXml(filename);

gsvirdi
412

Boss liked the utility. I got an official idea to develop :)....................... That one would be very different, but let me see how will I start with it. This one is similar to the above application. Difference is I need not have DateTime thing, Only date is required which I think will simplyfy the process. But... But..... the New development is that I'm supposed to have a Project column now. so the xml will become something like <cni> <Project1><Date></Date><Rev></Rev><Document></Document></Project1></cni>..... .... ..... and the contents (Display) of this xml should be restricted to different users. Means a user can see only his Projects.....

gsvirdi
412

I'll start a NEW thred for this one.... Thx Vulpes soooooooooooooooooooooo much for every bit of help :)

Feedback