Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Data Binding

Status
Not open for further replies.

ROGERDODGE

IS-IT--Management
Aug 13, 2003
40
0
0
GB
Hi

I'm fairly new to C# and .NET coming from Visual FoxPro.

I have a Windows Form with TextBoxes which have been data-bound to a DataSet. Everything works fine as I scroll up and down the dataset.

I am struggling with a few issues (primarily of understanding since I am self-taught)

1) How can I detect if any of the textboxes have been edited so that I may set a flag to prompt the user along the lines of "Changes have been made - do you wish to save them" I am really try to adding an event to each text box. I have played about with OnRowChanging etc within the DataSet but have completely drawn a blank.

2) When I do make changes to the field, I am having trouble reflecting these changes back to the underlying database by using the daAdapter.Update(ds,"table") function. It simply does not work? I have got it all working by defining my own UpdateCmd and executing a cmdUpdate.ExecuteNonQuery() command. Before I do so, I have to explicitly code every textbox.Text value to my Update Command parameters. This is a b@ll-ache particularly with data records of 100+ fields.

Surely the idea of binding datasets to textBoxes is to have a two-way reflection of data? Did I miss something.

Any pointing in right directions would be most appreciated

Roger
 
if you aren't using the CommandBuilder in the IDE. I recommend using the HasChanges method of the dataset. Note that it is sensitive to any field being set, even if the field is set to the value it already has. For example:

Code:
DataRow row = MyTable.Rows[0];

row["MyField"] = row["MyField"];

will cause HasChanges to return true even though you didn't actually change MyField.

As for daAdapter.Update, you will need to populate the parameters collection manually, making certain that you include the sourceColumn. The specific classes you use depends on the data provider you are using:

Code:
MySQLParameter[] prm = new MySQLParameter[2] {
   new MySQLParameter("@Name", DbType.String, "Name"),
   new MySQLParameter("@ID", DbType.String, "ID"),

adp.UpdateCommand = new MySQLCommand(
   "UPDATE builders " +
   "SET " +
      "Builder_Name = @Name, " +
   "WHERE Builder_ID = @ID");
adp.UpdateCommand.Parameters.AddRange(prm);

//Here, ID would be the name of the field in your
//DataTable in code and Builder_ID would be the name
//of your field in the database

Also, some provides require that you use a "?" instead of a "@" to delimit parameter names. Some don't allow you to even name the parameters.
 
hi dalchri - Thanks for responding

Unfortunately, my last post didn't make it as I lost contact with the server :-(

What I am actually after is an event that I can hook into which will fire when any row/column gets changed as opposed to a check method to tell me if they changed.

Thanks for the feedback re: the Update. It's more or less what I am doing. I have a suspicion that its the "bound" text boxes are not reflecting back to the dataset? Does that make sense. I will need to figure a way of proving/finding out if this is the case. Perhaps put a data grid temporarily.

Roger
 
I've found that the only way to force data from the controls back into the dataset is by:

Code:
//this <- a reference to the parent form
this.Validate();

Table.ColumnUpdated will provide you with event notification of changes to the DataTable as they are made.
 
It would seem the only way that I can get anything back to the dataset is by declaring a CurrencyManager for the DataSet and then on the 'leave' event of the TextBox, I call - cm.EndCurrentEdit() This indeed updates the DataSet. I have included a "Save" CommandButton to Update the Dataset. Sooooo, now all I need to to is to find a way of flagging the fact that some data on the form has been changed - I can then Enable the Save button and trap this is the user tries to close or leave the form.

Any clues, anybody?

Roger
 
What I do is rather than enabling/disabling the save button is just leave it enabled. This is the way that Word, VS.NET, and all other MS document management programs work.

Then, I check for changes using DataSet.HasChanges when the user presses the save button and if there are none, I do nothing.
 
dalchri - makes sense re: the 'Save' button - thanks.

I guess I'm just going to have to add the call to the CurrencyManager on each TextBox's 'Validated' event to make sure the DataSet reflects the changes made?

I have been looking into creating a custom TextBox class with built-in call to the CurrencyManager, but haven't quite got my head around this yet!

Thanks for your input - very helpful
Roger
 
When you use DataBindings to bind a control (let say a TextBox) to a source (let say a DataSet) everything is changed is the Text property is reflected in the DataSet and whenever the DataSet bound to text will change that text will be automatically reflected in the TextBox. You can change this process by using of the BindingManagerBase object.
Code:
public DataSet ds; // Assume this ds contains MyTable DataTable and there is a column named "LongName"
textBox1.DataBindings.Add(new Binding ("Text", ds, "MyTable.LongName"));

To suspend or resume the binding:
SuspendBinding() - when you don't allow the DataSet to be modified
ResumeBinding() - when you allow DataSet to be modified
Code:
BindingManagerBase bm = this.BindingContext[ds];
bm.SuspendBinding();
//..
bm.ResumeBinding();

To detect if the MyTable was modified override the ColumnChanged event and filter there the column or enable the Save button:
Code:
ds.Tables["MyTable"].ColumnChanged += new DataColumnChangeEventHandler( dt_Column_Changed );
private void dt_Column_Changed( object sender, DataColumnChangeEventArgs e )
{
	System.Windows.Forms.MessageBox.Show(string.Format( "Column_Changed Event:Column={0}; value={1}",  e.Column.ColumnName, e.Row["LongName"])); 
}

To update back the database there are many ways.
One is to use a CommandBuilder object and call Update() on the DataAdapter object associated to commandbuilder object. If Update() succeeds then call AcceptChanges() on the DataSet.
-obislavu-
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top