0

I have a question about how to setup components in a winforms application so they can interact with each other. But I want to use the visual designer to set this up.

What I have is a component called myDataBase and a component called myDataTable.
Now the component myDataTable has a property of type myDataBase. So in code I can do

myDataBase db = new myDataBase();
myDataTable dt = new myDataTable();
dt.DataBase = db;

The property DataBase in component myDataTable is public, so I can also use the visual designer to assign the DataBase property.

enter image description here

Now for my problem. I have many many forms that have one or more components of myDataTable on it.
I only want one instance for myDataBase.

What I do now is I create a component myDataBase dbMain = new myDataBase() on the mainform.
On every form I have to set the property for all myDataTable components to this dbMain.
I have to do this in code because the visual designer cannot see the dbMain component on the mainform.

So the question is, can I create one instance of component myDataBase that is visible to the visual designer on all forms, so I can use the visual designer to set the property of myDataTable components ?

For those that now Delphi, I want something like the DataModule in Delphi.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
GuidoG
  • 11,359
  • 6
  • 44
  • 79

1 Answers1

1

You can't without some code.

The easiest thing you can do, as far as I am concerned, it to create a base form, deriving from Form, and in that form, you make a property pointing to a singleton instance of your database object. You can bind to that property, and still keep it as simple as possible.

You just need to make your form derive from this one:

public class DatasourceForm : Form
{
    public myDataBase DataBase
    {
        get
        {
            return myDataBaseFactory.Current;
        }
    }
}

And the factory in charge of creating the singleton database instance:

public class myDataBaseFactory
{
    private static readonly Lazy<myDataBase> lazy =
    new Lazy<myDataBase>(() => new myDataBase());

    public static myDataBase Current { get { return lazy.Value; } }
}

(Singleton implementation from here)

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • Personally, I prefer [`Lazy`](https://msdn.microsoft.com/en-us/library/dd642331%28v=vs.110%29.aspx) for creating singletons ;-) – Uwe Keim May 04 '15 at 08:19
  • 1
    @UweKeim: Okay :) I do too actually. – Patrick Hofman May 04 '15 at 08:21
  • All my forms are descendants of a baseform so I can easily implement this. But will the visual designer be able to see the property myDataBase on the inherited forms ? – GuidoG May 04 '15 at 08:24
  • I just tried this and the problem remains that the visual designer on an inherited form cannot see this property so I still have to do everything in code. – GuidoG May 04 '15 at 08:31
  • @GuidoG: You could add a [`BindingSource`](https://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource%28v=vs.110%29.aspx) instance that points to `this`. In that way you can bind to the property. Not sure if it is possible to add that on the base form. – Patrick Hofman May 04 '15 at 08:58
  • That only solves part of the problem. I already have a bindingsource on my baseform and its DataBase property is set in the constructor. But there are lots of forms that need addidional bindingsources and myDataTables and what I wanted to do is set the DataBase property of these myDataTables using the visual designer and there the problem will remain – GuidoG May 04 '15 at 09:11
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/76867/discussion-between-patrick-hofman-and-guidog). – Patrick Hofman May 04 '15 at 09:12