dcsimg
Results 1 to 3 of 3

Thread: Mappng a BindingSource.DataSource to an instance of a Form?

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Mar 2013
    Location
    San Francisco, CA
    Posts
    253

    Mappng a BindingSource.DataSource to an instance of a Form?

    Is there a way to find the form in a Windows Forms application that uses a specified DataTable as the form's BindingSource.DataSource?

    For example, if I know the DataTable.Name how can I find the form(s) that is/are bound to that DataTable?

  2. #2
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    104,145

    Re: Mappng a BindingSource.DataSource to an instance of a Form?

    The question doesn't really make sense as asked. A BindingSource is not a standard part of a form. BindingSources are objects like any other, so they may be assigned to member or local variables, just like any other objects. A form may make use of zero, one or more BindingSource objects that may be assigned to member or local variables at any particular time.

    Just like any other problem, you should first think about what it is that you're actually asking for, what would be involved in such a thing and then consider the code required to implement it. You are making the common mistake of trying to go from a vague idea directly to code and then, when you can't, you give up and expect someone else to do it for you. Instead of that, think about the individual parts of the problem.

    Firstly, you need to find out whether a form is actually using any BindingSource(s). I'm going to assume that you are only interested in those that are added to the form in the designer. In that case, the form will have one or more member variables of that type. How do you determine whether that is the case? Don't know? Try to find out. Such information will already be out there but you have to look for it. Once you've got the BindingSource object, you can then check whether it is bound to a Datatable, either directly or via a DataSet. Once you get a DataTable, determining what it's name is should be a doddle.

    Of course, these forms would have to exist for you to do this. A type with no instances isn't bound to anything.

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Mar 2013
    Location
    San Francisco, CA
    Posts
    253

    Re: Mappng a BindingSource.DataSource to an instance of a Form?

    Hi jmc -

    Thanks again for taking time to address my question. Sorry if it was vague. Before I added a lot of detail (possibly superfluous/distracting), I was hoping that somebody might point me in the right direction, which you did:

    Firstly, you need to find out whether a form is actually using any BindingSource(s). I'm going to assume that you are only interested in those that are added to the form in the designer. In that case, the form will have one or more member variables of that type. How do you determine whether that is the case? Don't know? Try to find out. Such information will already be out there but you have to look for it. Once you've got the BindingSource object, you can then check whether it is bound to a Datatable, either directly or via a DataSet. Once you get a DataTable, determining what it's name is should be a doddle.
    Your reply hinted that there is a difference if the BindingSource component is added via the designer vs. via code. What is the distinction?

    The backstory of my question:
    My projects usually have lots of forms that have bound data, most often via a BindingSource that is declared at runtime via code.
    Code:
    Private WithEvents bsMain As New BindingSource
    By convention, I always name the principal BindingSource to be "bsMain" (e.g., the top-level BindingSource in a parent-child data relation).

    These BindingSource components have their DataSource property set to a DataTable.
    Code:
                With bsMain
                    .DataSource = Nothing
                    .DataMember = "Portfolios"
                    .DataSource = dsMain
                    .Sort = "PortfolioName"
                End With
    Other BindingSource components on my forms are usually bound to a parent-child data relation.
    Code:
                With bsAccounts
                    .DataSource = Nothing
                    .DataMember = "Portfolio_Accounts"    '...bind to relationship
                    .DataSource = bsMain
                    .Sort = "AccountName"
                End With
    I use a delegate for handling the ColumnChanged event of each bound DataTable that has user-editable columns.
    Code:
    AddHandler dsMain.Tables("Portfolios").ColumnChanged, AddressOf Column_Changed
    My forms have a Column_Changed procedure that sets/clears a public property of the form (flgFormDirty).
    Code:
                tbl = CType(sender, DataTable)   '...the sender is a BindingSource
    
                If e.Column.ColumnName <> "ModDate" Then
                    '...this fires the bound DataTable's ColumnChanged event that will
                    '   in turn call the Column_Changed procedure (again)
                    e.Row("ModDate") = Date.Now
                End If
    
                If Not flgFormDirty Then flgFormDirty = True   '...form's public property
    Each form as a Public property (flgFormDirty) that enables/disables the Save and Cancel command buttons, and (if the application is compiled as a Debug build) displays the form's "Dirty" status.
    Code:
        Public Property flgFormDirty As Boolean
            Get
                Return _FormDirty
            End Get
            Set(ByVal value As Boolean)
                Dim timer As New Stopwatch
                _FormDirty = value
                If _FormDirty = True Then
                    btnSave.Enabled = True
                    btnCancel.Enabled = True
                Else
                    btnSave.Enabled = False
                    btnCancel.Enabled = False
                End If
                If IsDebugMode() Then
                    If _FormDirty = True Then
                        tsslFormDirty.ForeColor = Color.Red
                        tsslFormDirty.Text = "Form is ""Dirty"""
                    Else
                        tsslFormDirty.ForeColor = Color.Black
                        tsslFormDirty.Text = "Form is ""Clean"""
                    End If
                    tsslFormDirty.Visible = True
                    ssMain.Refresh()
                    timer.Start()
                    Do While timer.ElapsedMilliseconds < 500   '...a 0.5 second "timeout"
                        System.Threading.Thread.Sleep(100)  '...wait 0.1 second
                    Loop
                    timer.Stop() : timer.Reset()
                    tsslFormDirty.Visible = False
                Else
                    tsslFormDirty.Visible = False
                End If
                timer = Nothing
            End Set
        End Property
    So with that background, here's the crux of my question:
    Instead of incorporating the Column_Changed procedure in every form, I would like keep it in a module that has general purpose procedures. The challenge is that the Column_Changed procedure sets/clears the flgFormDirty property of a specific form (so I would need a reference to that form). I think there are 3 ways that this could be done:
    1. I could pass the form to the Column_Changed procedure, but I haven't figured out how to do that because I think it has to be done via the delegate that I've shown above. I think, if possible, this would be the "cleanest" approach.
    2. I could iterate through the Application.OpenForms collection and then for each form in the collection iterate through all the form's BindingSource components. For each found BindingSource, check its DataSource property for the DataTable that includes the Column being changed. I think that this approach is what you suggested.
    3. I could create a global array (or custom collection?) of form objects and their BindingSource components and each time the Column_Changed procedure is called, iterate through the array to identify the form object that is bound to the DataTable that includes the Column being changed.

    I'm sorry if there's too much detail here, but I hope that it clarifies my original question.

    One final comment...

    ...when you can't, you give up and expect someone else to do it for you...
    I am not giving up on this problem nor am I asking for someone else to do it for me! I'm just trying to better understand how to get started and what would be the best path forward to take. Maybe there's no solution, I don't know. But, without the advice of experts like you this would be much more difficult to figure out. As I said earlier in this post, I always struggle with what is the right amount of information to share (too much detail and I'm afraid a lot of folks will just "eye roll" and move on...).

    Thanks again for your helpful input, I *ALWAYS* learn a lot from your comments.
    Last edited by Mark@SF; Aug 24th, 2019 at 01:02 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width