Solved

Manually editing content of datatable row

Posted on 2006-06-28
8
942 Views
Last Modified: 2010-05-18
vb2005

i have added a dataset, tableadapter and bindingsource to a form using vb2005 visual designer.

i have some textboxes bound to datatables on the dataset.

what i want to know is, can i manually edit the content of the bindingsource current row of data for a specified column?

in other words, the bindingsource is connected to a table on the access database, and each row has a lot of columns. in the form i use a binding navigator which scrolls through the rows when i click on the arrow and fills the textboxes with the data accordingly. i want to change manually, in code, the content of column "DATE" for example, for a given row position the navigatior is currently in.
i want my manual changes to be updated to the database when i .endedit the bindinsource and call update on the tableadapter.

thanks
0
Comment
Question by:newyuppie
  • 4
  • 4
8 Comments
 
LVL 34

Expert Comment

by:Sancler
Comment Utility
Yes you can.  That is essentially what databinding is all about.  Are you having problems doing it?  If so, what?

Roger
0
 
LVL 13

Author Comment

by:newyuppie
Comment Utility
hi roger (im still testing some things on my other question which you are helping me... will answer shortly)

specifically, i added to a form a treeview which i need to be bound to a datatable. so, as i have a lot of other bound textboxes, i also need to store the selected node text into a column in the datatable. what i need to know is what is the best way to proceed:

a) store the value on the bindigsource.current("columnname")
b) store it on the dataset directly (i dont know how to do this)
c) other method

0
 
LVL 34

Expert Comment

by:Sancler
Comment Utility
Ah, I see I missed the point rather.  I now understand that you need manually to insert a value in the datasource because - although you are referring to the control as "bound" that "binding" is one you are having to code yourself because the Windows Forms version of the TreeView does not support databinding in the "normal" sense.

On that understanding, (a) is the way to go.  You can manually edit any value in the datasource.  All you need to do is find the relevant row and, within that, the relevant column.  Given that BindingSource.Current is already pointing to the row, and ("ColumnName") identifies the column

bindingsource.current("columnname") = <new value>

should do it.  That will propagate the change back to the dataset.  You will then need code - probably triggered by BindingSource.PositionChanged - to read the data from that row/column in the datasource and find, and select, the relevant node in the treeview.

Roger

0
 
LVL 13

Author Comment

by:newyuppie
Comment Utility
roger,
putting the bindingsource.current piece of code in the BindingSource.PositionChanged event does indeed work and thus this question could be considered PAQed.

nevertheless, if you could further assist me in the lines of this question, i have an issue if i put the bindingsource.current code in the BindingSource.ListChanged event, it throws an argumentexception, as if there was no Current method inside this event. the reason i want to put the code in here is because i need to manually edit a column named DateAdded, which i want to store the Date.Now() value whenever i ADD a new row to the bindingsource. since i couldn't find any BindingSource.Added (only AddingNew but thats fired before the addition and .Current method doesnt work here either), i am a bit stuck on that one.

thanks!
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 34

Expert Comment

by:Sancler
Comment Utility
No, the ListChanged event doesn't have a .Current property/method.  The ListChangedEventArgs are described here

http://msdn2.microsoft.com/en-us/library/system.componentmodel.listchangedeventargs_members.aspx

As you can see, they are all related to the underlying list (the binding source's datasource) rather than to the BindingSource itself.  You could, in theory, still refer to BindingSource.Current within the handler for that event.  But in practice I would advise against it.  This is because (although I haven't tested) it looks likely to me to get into an infinite loop.  You are in listchanged.  You alter the list.  It fires listchanged. You come back into listchanged. ...

What is wrong with this approach.  One form, one button, one datagridview called dgv

Public Class Form1
    Dim dt As New DataTable("MyTable")
    Dim bs As New BindingSource

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        maketable()
        bs.DataSource = dt
        dgv.DataSource = bs
        bs.Sort = "ID desc"
    End Sub

    Private Sub maketable()
        Dim dc1 As New DataColumn
        dc1.ColumnName = "ID"
        dc1.DataType = GetType(Integer)
        dt.Columns.Add(dc1)
        Dim dc2 As New DataColumn
        dc2.ColumnName = "CreationDate"
        dc2.DataType = GetType(DateTime)
        dt.Columns.Add(dc2)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Static i As Integer = 0
        bs.AddNew()
        bs.MoveLast()
        bs.Current("ID") = i
        bs.Current("CreationDate") = Now
        bs.EndEdit()
        i += 1
    End Sub

End Class

Most of the code is just setting up dummy objects with which to work.  What you might find useful is the code in Button1_Click.  Add the new record.  It will always go at the end.  Use .MoveLast to go to it.  It is now .Current.  Make whatever manual changes you want.

Incidentally, you will see that I call bs.EndEdit.  That may seem inconsistent with what I said in an earlier post.  But there is a specific reason for doing that here.  It is so that the new record will be moved from its "last" position into its "sorted" order for display in the datagridview.  A new record only stays at the end until the first edit on it has been ended.

Roger
0
 
LVL 13

Author Comment

by:newyuppie
Comment Utility
how would i place the code of Button_Click into an event that handles the BS add record event and thus will be created when i click the "plus" sign on the binding navigator? as of now, the plus sign triggers automatically the addition of a new record. does the plus sign trigger before the addition or after? are the _listchanged, _positionchanged events triggered before or after the addition? before or after the plus sign event?

im thinking along the lines that i could place this code:
bs.Current("ID") = i
bs.Current("CreationDate") = Now
bs.EndEdit()

on the event handler of plus sign's click if the record is added before the click event and that maybe solves part of the problem. another part of the problem could be that when i first load the form, i have this code in the _Load event:

<CODE>'if new form, add new item to start with
If Me.SolicitantesBindingSource.Count = 0 Then Me.SolicitantesBindingSource.AddNew()</CODE>

this makes a new record if the form is a new one, and doesnt add one if the form is loading data from a stored database. if the form is new i create a database according to a template, if its not new, i load a previously stored database.
0
 
LVL 34

Accepted Solution

by:
Sancler earned 500 total points
Comment Utility
Here's revised code.  Form as before, but with BindingNavigator replacing the button.

Public Class Form1
    Dim dt As New DataTable("MyTable")
    Dim WithEvents bs As New BindingSource

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        maketable()
        bs.DataSource = dt
        dgv.DataSource = bs
        bs.Sort = "ID desc"
        bn.BindingSource = bs
    End Sub

    Private Sub maketable()
        Dim dc1 As New DataColumn
        dc1.ColumnName = "ID"
        dc1.DataType = GetType(Integer)
        dt.Columns.Add(dc1)
        Dim dc2 As New DataColumn
        dc2.ColumnName = "CreationDate"
        dc2.DataType = GetType(DateTime)
        dt.Columns.Add(dc2)
        Dim dc3 As New DataColumn
        dc3.ColumnName = "OtherData"
        dc3.DataType = GetType(String)
        dt.Columns.Add(dc3)
    End Sub

    Private Sub bs_AddingNew(ByVal sender As Object, ByVal e As System.ComponentModel.AddingNewEventArgs) Handles bs.AddingNew

        Static adding As Boolean = False
        Static i As Integer = 0
        If adding Then Exit Sub

        adding = True
        Dim dr As DataRowView = bs.AddNew
        bs.MoveLast()
        dr("ID") = i
        dr("CreationDate") = Now
        e.NewObject = dr
        bs.EndEdit()
        i += 1
        adding = False

    End Sub

End Class

Code differences are that the bindingsource is declared WithEvents to give access to its AddingNew event.  And the code from Button1 (modified) is put in the sub for that event.  The boolean is necessary to stop the bs.AddNew in the code firing the AddingNew event again - infinite loop ;-)  Then its a similar approach to before but with slightly different objects.  What we have to do is interrupt the automatic process of creating a totally blank new record.  We do that by creating the record we want and then passing it in as the .NewObject to replace the blank record that would otherwise by created.

Roger
0
 
LVL 13

Author Comment

by:newyuppie
Comment Utility
(tightly related to my other question http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21900684.html which Roger also won the points)

thanks for your help Roger, based on both your answers (from this Q and the linked one) i was able to write succesfully code in the PositionChanged of the BindingSource. although i haven't tried to use the code you provided for the _AddingNew event of the bindingsource, its another way to look at this issue.

i ended up using the .Current property of the BindingSource and put a similar code on the _PositionChanged event. i thought i got a bit more flexibility since that code is called a lot in comparison to the _AddingNew event, in which i get only one shot for formatting the added data.

anyway thank you very much again,

P
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

If you're writing a .NET application to connect to an Access .mdb database and use pre-existing queries that require parameters, you've come to the right place! Let's say the pre-existing query(qryCust) in Access takes a Date as a parameter and l…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now