Monday, August 16, 2010

C# windform datagrid update event?

I have a datagrid that I update every minute using a timer, data adapter and a stored procedure. I want to have an event that can be trigured if the contents of the datagrid change (but change from its last state, not everytime the datagrid is refilled)... example if a row is added or the value in a column changes. Could someone point me to a resource that will explain how to achieve this? Seems to be loads of help on events that are triggered manually, but little on the above.Thank youC# windform datagrid update event?
Hello,





Before I continue, this topic is an intermediate -%26gt; advanced discussion since we will be using Events, Override Cloneable, Override Equal, etc... If you would need to know more about those terms, search on your favorite search engines to know more about them. I am just explaining how to solve your problem





Your absolutely right, the change event occurs even if you type the same thing. I would create my own datastructure that holds the contents of that table. Let me explain in detail what I mean.





Say you have a simple table called Users, where in the datagrid it will display the Users info (name, age, description), sure you can have more complex items, but for presentation purposes, I will just have these 3 details. I would create an object called UserDetail.





===========================


class UserDetail { ... }


===========================





Within that class, I will override Equals operator, and within that equals I will do something like this:





===========================


public override bool Equals(object obj)


{


UserDetail tmp = obj as UserDetail;


if(this.name == tmp.name %26amp;%26amp; this.age == tmp.age %26amp;%26amp; this.desc == tmp.desc)


{


return true;


}


else


{


return false;


}


}


===========================





Where name,age, desc are just properties of that UserDetail class. Now we can compare objects, for instance using the == or Equals method. The reason why we did this is to represent each row as an object, where in this case it is the User Object, BUT we need to represent the whole DataGrid as an object that we can work with. So we can create a simple List%26lt;UserDetail%26gt; and add all the rows of the datagrid as UserDetail objects in that List.





I will place that list in a class calling it UserData





===========================


class UserData


{


public List%26lt;UserDetail%26gt; Users;





public override bool Equals(object obj)


{


UserData tmp = obj as UserData;





// Check the size


if (this.Users== null || this.Users.Count != tmp.Users.Count)


return false;





// If size are the same check contents


foreach(UserDetail ud in this.Users)


if (!tmp.Users.Contains(sd))


return false;





// Everything passed, return true


return true;


}


}


===========================





Obviously, evertime you want to override Equal you need to override GetHashCode, so just include this in both classes:





===========================


public override int GetHashCode()


{


return base.GetHashCode();


}


===========================





AS you see, I am creating a simple datastructure that represents the DataGrid. We did that because we want the datastructure to see if any change occured! So you can have a simple Property called DataChanged within your main class.





===============================


// Original Data


public UserData data;





// The data that is changed


public UserData changedData;





/// %26lt;summary%26gt;


/// Data Changed!


/// %26lt;/summary%26gt;


public bool DataChanged


{


get


{


if (!data.Equals(changedData)) return true;


else return false;


}


}


==============================





So you will be wondering, what do we have two UserData, the reson behind this is because we want to manage the *changed data* with the ';original data';. So when you fire up the application, you would place all the data within the data object, and copy that exact same data to changedData





( NOTE: in .NET copy is by reference, and in this case we don't want it by reference, we want two distinct objects that have different references so a simple changedData = data WILL NOT WORK. The same way you loaded the original data to ';data'; object, you will have to do the same to ';changedData'; object. That might take double the time, but if you want to enhance your application, I would recommend overriding Clone method. When you override the Clone method (search online for more info) you can do the following changedData = data.Clone(); . After you have cloned your object, you overall application will use the changedData as its main variable to work with cause that is what you want. You want to compare if the current data differs from the previous entered data.





So how will we apply an event in this case? Everytime a data has been changed (the default change event handler for the Datagrid) you will trigger the DataChange Property..





In that event, you will just do the following (note my main class is called manager):





==============================


if (dataManager.DataChanged)


{


// Refill Database


}


else


{


// Do nothing


}


==============================





Sure you can create another event in the first if statement, it all depends on what your doing.





Good Luck.

No comments:

Post a Comment