ePlaice / For the Best Software on the Net

Mainly Free and Open Source Software


Software Dev't Navigation

Delphi Conversion | DataSets | DataGridView | Record Navigation | Data Formatting / Validation | Data Queries Data Input Form Data Readers MDI Forms Charts Using MySQL | MySQL NET Connector |

Valid XHTML 1.1

Latest news

27 Feb 2007: I decided to write a few lines about my experiences with C# and SharpDevelop, but got waylaid looking at some of my earlier experiences.

07 Mar 2007: SharpDevelop 2.1 Final has been released.

Links:

Record Navigation

SharpDevelop

It was bit of a shock after Delphi to have to learn how to navigate through a database. In Delphi it is just a question of adding a DBNavigator component to the form hooking it up to a Datasource and away you go with no further programming. Recently I have found that if you use the BindingSource and BindingNavigator things are much simpler than using Currency Manager as I have detailed here. I have updated this page showing that there is not much more code involved using SharpDevelop over a fully visual solution and also over Delphi .

I also found it a bit more troublesome to write a useful search procedure which is comparable to Delphi. So I have included a few notes on an incremental search method that I am using in C#. I am still not entirely happy with this and will try to improve when I have time.

Using BindingSource and BindingNavigator

I have now updated all my applications to use these new components available in NET 2.0. In fact these components are very simple to use and save a lot of effort over the Currency Manager method detailed below.

Form Layout

From the toolbox drop a BindingSource and a BindingNavigator on the form, which you can either dock at the top or bottom of the form.

Bind to Textboxes

You then need to reference the bindingsource to the dataset and to the bindingnavigator :-

bindingSource1 = new BindingSource(dataSet1,"author");
bindingNavigator1.BindingSource bindingSource1;>  

Then set up the bindings to the textboxes; for example

textBoxAuthorNo.DataBindings.Add("Text",bindingSource1,"authno");

Bind to RadioButton Group

To bind a RadioButton Group to a single database field does not appear to be supported whereas in Delphi this is 'Oh' so simple. However, It seems there is a fairly straightforward workaround involving setting up a boolean field on the database for each radio button in the group. Note that 'servhot', 'servcold', 'servroom' are defined as TinyInt(1) which seems to be the MySQL equivalent of Boolean. From reading the forums I noticed there seemed to be much confusion about using Boolean fields in MySQL and I was concerned whether the following approach would work. I have now tested it out and it all seems to work OK. First set your fields as Boolean which MySQL Administrator automatically set to TinyInt(1). Then bind all your Radio Buttons in each Group as follows :-

// Radio Button Group Serv Temp Databinding
radioButton1.DataBindings.Add("Checked", bindingSource1, "servhot");
radioButton2.DataBindings.Add("Checked", bindingSource1, "servcold");
radioButton3.DataBindings.Add("Checked", bindingSource1, "servroom");

Then add your Command Update Parameters using a MySqlDbType of Byte (Note there is no MySqlDbType of TinyInt or Boolean - but maybe in the future!!):

da1["recipe"].UpdateCommand.Parameters.Add("?servhot", MySqlDbType.Byte, 1"servhot");
da1["recipe"].UpdateCommand.Parameters.Add("?servcold", MySqlDbType.Byte, 1"servcold");
da1["recipe"].UpdateCommand.Parameters.Add("?servroom", MySqlDbType.Byte, 1"servroom");

Then in your update statement :-

recipeRow[0]["servhot"radioButton1.Checked;
recipeRow[0]["servcold"radioButton2.Checked;
recipeRow[0]["servroom"radioButton3.Checked;

Bind to a DataGridView

This is even simpler, where 'authorbook' is a data relation which supports a master detail relationship :-

dgv2.DataSource bindingSource1;
dgv2.DataMember "authorbook";

Conclusion

There is very little coding involved with this approach because you don't need to set up a view and you don't need to write any code to control the navigation buttons and you also get for free the total number of records and the current position.

Currency Manager Approach

With NET 2.0 it is advocated to use the new BindingSource and BindingNavigator in preference to Currency Manager. However, if you wish to stick with Currency Manager then the following works quite well.

Setting Up a View

When you are navigating through records in a database it is required to set up a view for the dataset you wish to navigate :-

dsView dataSet1.DefaultViewManager;

This will then be used by CurrencyManager to position the current record.
Then just drop four buttons on the form called FirstBtn, PreviousBtn, NextBtn and LastBtn and code the following events :-

First Button Click

void FirstBtnClick(object sender, EventArgs e) 

CurrencyManager cm 
(CurrencyManager)this.BindingContext[dsView,"t_item"]
cm.Position 0
fnEnableDisableButtons(firstBtn, previousBtn, false)
fnEnableDisableButtons(lastBtn, nextBtn, true)

}

Previous Button Click

void PreviousBtnClick(object sender, EventArgs e) 

CurrencyManager cm 
(CurrencyManager)this.BindingContext[dsView,"t_item"]
if 
(cm.Position >1

cm.Position--

fnEnableDisableButtons(lastBtn, nextBtn, true)

if (cm.Position == 0

fnEnableDisableButtons(firstBtn, previousBtn, 
false)


Next Button Click

void NextBtnClick(object sender, EventArgs e) 

CurrencyManager cm 
(CurrencyManager)this.BindingContext[dsView,"t_item"]
if 
(cm.Position < cm.Count -

cm.Position++

fnEnableDisableButtons(firstBtn, previousBtn, true)

if (cm.Position == cm.Count - 1

fnEnableDisableButtons(lastBtn, nextBtn, 
false)


Last Button Click

void LastBtnClick(object sender, EventArgs e) 

CurrencyManager cm 
(CurrencyManager)this.BindingContext[dsView,"t_item"]
cm.Position cm.Count - 1
fnEnableDisableButtons(firstBtn, previousBtn, true)
fnEnableDisableButtons(lastBtn, nextBtn, false)

Enable/Disable Button Function

private void fnEnableDisableButtons(Button bt1, Button bt2, bool b) 

bt1.Enabled
=b
bt2.Enabled=b

Searching Records

I like to have an incremental search facility which has the capability of incrementally searching on a number of database fields and then allowing the user to select the wanted record and go straight to the relevant record. The way I have implemented it so far is to have a form with textbox1 and a datagridview showing selected fields from the dataset I am searching. I am then searching against the database field "item". I am very disappointed that I could not find a true incremental search in NET 2.0 because the solution in Delphi works and is much, much simpler. So here is the fairly cr***y solution I came up with after trawling through a number of articles. :-

void TextBox1TextChanged(object sender, EventArgs e)
{
dataSet1.Tables[
0].DefaultView.Sort "item";
 
DataRow[] rows dataSet1.Tables["contents"].Select(string.Format("item LIKE '{0}*'",textBox1.Text));
 
// Do we have any row's that meet the search criteria
if (rows.Length > 0)
{
int dataSet1.Tables[0].DefaultView.Find(textBox1.Text);
if 
(i >0)
// set the Position for the first row that was found
this.dataGridView1.Rows[i].Selected = true;
bindingSource1.Position i;
GlobalClass.GlobalVar i;
}
else {
MessageBox.Show(
"No row found that matches " + textBox1.Text);
}
}

If any one has a proper solution please let me know. Also I have modified this to work with a bindingsource instead of Currency Manager.