A quick Newbie to NET question

  • Thread starter Thread starter Robert Meek
  • Start date Start date
R

Robert Meek

I recently began working with NET via VS 2005 and the Chrome Object
Pascal IDE add-on as I have no experiance with other languages. But i am
picking up C# as I go along...a consequence of having to read C# code in the
books I'm learning from.
I'm used to creating and then freeing and making nil all my secondary
forms as they are needed and no longer required because it saves on
resources thru the application session, and though I have no problem
creating an instance of my secondary form type and displaying it from the
NET project's MainForm, I would also like to be able to check if that
particular instance is in memory or not from some other secondary form and
if so just show it and bring it to the front of the screen, or if not,
create an instance of it.
One nice thing about Chrome is that it does allow you to use Globals if
you like, but I'm not sure if my definition of Globals is the same as NET's,
but in any case what I've been doing is adding a var of the secondary Form
type in the public section of my mainform's class definition. And then
create a new method also in the MainForm's public section which checks to
see if my form instance is nil or not and creates and/or shows it as
required. This method is then called by a button or menu item on the
mainform whose event is in the MainForm's Private section.
This part works just fine, and I can close the form and make sure it is
released by having button event on the secondary form instance itself which
calls the form's Dispose method. But if I have the required MainForm in
which the second Form's instance variable is declared in I cannot create
that instance or even do anything with it from an event on a third form! It
tells me I have to create a new instance in order to do so. But that leaves
me in a position where the user could possibly create multiple instances of
the same Form type and I don't wish to allow that. I just want to to allow
the user to create one instance of the Form type, but from any other Form in
the project. And if the Form instance is already created, then I just want
the user to be able to bring that instance to the front of the screen from
any other Form!
I realize I took a long time to state a simple problem but as this is
new to me I wanted to be sure I was understood. Any help would be
appreaciated!
 
Robert said:
I recently began working with NET via VS 2005 and the Chrome Object
Pascal IDE add-on as I have no experiance with other languages. But i am
picking up C# as I go along...a consequence of having to read C# code in the
books I'm learning from.
I'm used to creating and then freeing and making nil all my secondary
forms as they are needed and no longer required because it saves on
resources thru the application session, and though I have no problem
creating an instance of my secondary form type and displaying it from the
NET project's MainForm, I would also like to be able to check if that
particular instance is in memory or not from some other secondary form and
if so just show it and bring it to the front of the screen, or if not,
create an instance of it.
One nice thing about Chrome is that it does allow you to use Globals if
you like, but I'm not sure if my definition of Globals is the same as NET's,
but in any case what I've been doing is adding a var of the secondary Form
type in the public section of my mainform's class definition. And then
create a new method also in the MainForm's public section which checks to
see if my form instance is nil or not and creates and/or shows it as
required. This method is then called by a button or menu item on the
mainform whose event is in the MainForm's Private section.
This part works just fine, and I can close the form and make sure it is
released by having button event on the secondary form instance itself which
calls the form's Dispose method. But if I have the required MainForm in
which the second Form's instance variable is declared in I cannot create
that instance or even do anything with it from an event on a third form! It
tells me I have to create a new instance in order to do so. But that leaves
me in a position where the user could possibly create multiple instances of
the same Form type and I don't wish to allow that. I just want to to allow
the user to create one instance of the Form type, but from any other Form in
the project. And if the Form instance is already created, then I just want
the user to be able to bring that instance to the front of the screen from
any other Form!
I realize I took a long time to state a simple problem but as this is
new to me I wanted to be sure I was understood. Any help would be
appreaciated!

You want to look at the Singleton design pattern. The description in
the Design Patterns book by the GoF is probably too general. I Googled
for C# design form and came up with several pages, including the
following quick summary:

http://www.dotnetspider.com/kb/Article1846.aspx
 
I'm not sure if you misunderstood me or if it's the way I did it because
it's a bit tough relating C# code to Object Pascal which I'm using via
Chrome. But using the singleton pattern and the link you suggested, I was
able to I believe basically write exactly the same code methods as shown but
in Pascal, and indeed from any form which I called my newInstance for
TestForm2, an instance of Testform2 is created and shown. And further if I
try to create a second instance of Testform 2 from the same form and event
as before, calling the NewInstance method a second time, the original
instance is merely brought to the front of the screen as want. The Problem
is though, is that once an instance of TestForm2 has already been created
and shown from let's say the MainForm event calling the NewInstance method,
and I then try to create it again from let's say Form3, it doesn't halt the
creation and merely bring the original instance to the front. It creates a
second instance of the same form! I need to allow the user to click on any
of the "Create Testform2" buttons that can be found, one on each of all the
forms in the projkect except of course Testform2, and have the application
create a new instance only if none has yet been created. If one instance is
currently in memory, then I want that same button click to merely bring the
TestForm2 instance to the front of the screen!
In Delphi win32 this was easy because when you created a form at
designtime and gave it a name, that name becoes a variable accessible from
any other unit in which it has been added to it's uses clause. So I could
for example merely do this from any other form and be assured that only one
instance of my TestForm2 was ever in memory at the same time:

if TestForm2 <> nil then
begin
TestForm2 := TTestForm2.Create(Self);
Testform2.Show
end
Else
begin
TestForm2.Show;
end;

But in NET, and even though I have Globals turned on, it seems that I
must create a new instance of the same form from anyplace I need the user to
be able to even if there's already an instance in memory! If this is true,
would there be some way of creating the new instance and at the same time
disposing of the old instance? I guess it's my long term with Delphi, but I
find it hard to believe there's no easy way of accessing the same object
instance from anywhere in the project...be it a Form or something else! For
example, suppose I created some kind of configuration file which held text
data that I might need to read into controls found on a number of different
forms at different times. I shouldn't need to create and load a seperate
copy of the file into memory each time I needed the information should I?
Again, I realize this is all very basic but I'm just getting started
with NET so please forgive me for being so dumb on this issue!
 
Robert said:
I'm not sure if you misunderstood me or if it's the way I did it because
it's a bit tough relating C# code to Object Pascal which I'm using via
Chrome. But using the singleton pattern and the link you suggested, I was
able to I believe basically write exactly the same code methods as shown but
in Pascal, and indeed from any form which I called my newInstance for
TestForm2, an instance of Testform2 is created and shown. And further if I
try to create a second instance of Testform 2 from the same form and event
as before, calling the NewInstance method a second time, the original
instance is merely brought to the front of the screen as want. The Problem
is though, is that once an instance of TestForm2 has already been created
and shown from let's say the MainForm event calling the NewInstance method,
and I then try to create it again from let's say Form3, it doesn't halt the
creation and merely bring the original instance to the front. It creates a
second instance of the same form! I need to allow the user to click on any
of the "Create Testform2" buttons that can be found, one on each of all the
forms in the projkect except of course Testform2, and have the application
create a new instance only if none has yet been created. If one instance is
currently in memory, then I want that same button click to merely bring the
TestForm2 instance to the front of the screen!

You're right: I didn't understand that from your original post.
However, it's easy to adapt the singleton pattern. Simply make
NewInstance a method that takes the calling form name as an argument,
then store one instance for each form in a Hashtable. As well, you
probably want to create a DeleteInstance method that each Form can call
in its Closing event. So:

public class TestForm2
{
private static Hashtable _instances = new Hashtable();

private TestForm2()
{
... usual stuff ...
}

public static TestForm2 GetInstance(string callingFormName)
{
TestForm2 instance =
(TestForm2)TestForm2._instances[callingFormName];
if (instance == null)
{
instance = new TestForm2();
TestForm2._instances[callingFormName] = instance;
}
return instance;
}

public static void DeleteInstance(string callingFormName)
{
TestForm2 instance =
(TestForm2)TestForm2._instances[callingFormName];
if (instance != null)
{
instance.Dispose();
TestForm2._instance.Remove(callingFormName);
}
}
}

and then, in another form, you can just call

TestForm2 form2 = TestForm2.GetInstance(this.Name);

to get the instance particular to this form, and:

protected override void OnClosing(CancelEventArgs e)
{
TestForm2.DeleteInstance(this.Name);
}

to throw away the TestForm2 instance when your parent form exits.
 
Robert said:
I'm not sure if you misunderstood me or if it's the way I did it because
it's a bit tough relating C# code to Object Pascal which I'm using via
Chrome. But using the singleton pattern and the link you suggested, I was
able to I believe basically write exactly the same code methods as shown but
in Pascal, and indeed from any form which I called my newInstance for
TestForm2, an instance of Testform2 is created and shown. And further if I
try to create a second instance of Testform 2 from the same form and event
as before, calling the NewInstance method a second time, the original
instance is merely brought to the front of the screen as want. The Problem
is though, is that once an instance of TestForm2 has already been created
and shown from let's say the MainForm event calling the NewInstance method,
and I then try to create it again from let's say Form3, it doesn't halt the
creation and merely bring the original instance to the front. It creates a
second instance of the same form! I need to allow the user to click on any
of the "Create Testform2" buttons that can be found, one on each of all the
forms in the projkect except of course Testform2, and have the application
create a new instance only if none has yet been created. If one instance is
currently in memory, then I want that same button click to merely bring the
TestForm2 instance to the front of the screen!
In Delphi win32 this was easy because when you created a form at
designtime and gave it a name, that name becoes a variable accessible from
any other unit in which it has been added to it's uses clause. So I could
for example merely do this from any other form and be assured that only one
instance of my TestForm2 was ever in memory at the same time:

I must apologize for my other post. Although the hashtable solution
will work, it's way overcomplicated for what you want to do.

A much tidier solution would be, in each Form that needs its own copy
of TestForm2, just do this:

public class OtherForm : System.Windows.Form
{
private static TestForm2 _form2 = null;

private static TestForm2 Form2Instance
{
get
{
if (_form2 == null) { _form2 = new TestForm(); }
return _form2;
}
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
}

This will give you one TestForm2 for OtherForm, no matter how many
OtherForms you have on the screen. If you want an exactly one-to-one
relationshp between OtherForms and TestForm2s (so, for example, you
could have two OtherForms on the screen, each with its own TestForm2
instead of one shared between them) then just remove the "static"
modifier on _form2 and Form2Instance, and add a this._form2.Dispose()
inside the "if (disposing)" statement in the Dispose method.

No need for a central hash table: just do the same thing in each Form
class.
 
Yes, I finally figured it out last night based on some other code pretty
much like what you just gave. It's really difficult for me not having had
any computer sci or programming education. Being self taught the only
thibng I know, and I believe I know it well, is Delphi! And Delphi I can
see now, as great as it is, makes one a lazy programmer in many respects.
Once can mix procedural and OOP code anyway they like, globals become
something one depends upon.
I do think however, that Object pascal, the layout of it's units and
such is a lot easier to understand and deal with than C# and certainly years
ahead of VB!
 
In C# How to open Already designed form

here ReportPackline is the name of form already exist

ReportPackLine form2 = new ReportPackLine();
form2.Show();

I hope this works

Ayaz Hoda
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top