Pleading for fresh eyes on my problem using a PropertyGrid with a Singleton 
Author Message
 Pleading for fresh eyes on my problem using a PropertyGrid with a Singleton

Greets everyone! I've been trying to solve this problem for about 3
hours now and I'm just coming up short and I'm keeping my fingers
crossed that a fresh set of eyes and a new perspective will help.
Here's the (very simplified) deal...

I have a Windows app with two forms and a Singleton. The Singleton has
one property. FormA holds the Singleton object, has a method for
toggling the boolean property in the Singleton and can launch FormB.
FormB has a PropertyGrid that is "bound" to the Singleton. Something
like this...

---start code---

public class Singleton
{
        private static Singleton singleton = null;

        public static Singleton GetInstance()
        {
                if(singleton == null)
                {
                        singleton = new Singleton();
                }
                return singleton;
        }

        private bool myProperty;

        private Singleton()
        {
                this.myProperty = true;
        }

        public bool MyProperty
        {
                get
                {
                        return this.myProperty;
                }
                set
                {
                        this.myProperty = value;
                }
        }

Quote:
}

public class FormA
{
        public Singleton MySingleton;

        public FormA()
        {
                MySingleton = Singleton.GetInstance();
        }

        private ToggleMyProperty()
        {
                MySingleton.MyProperty = !MySingleton.MyProperty;
        }

Quote:
}

public class FormB
{
        public FormB
        {
                this.propertyGrid.SelectedObject = MySingleton.GetInstance();
        }

Quote:
}

---end code---

My problem is that no matter what I do to the property, the
PropertyGrid never displays the updated result. For example...

1. Run program
At this point MyProperty = true thanks to the Singleton's constructor.

2. FormB.Show
MyProperty is still true and the PropertyGrid on FormB shows this.

3. FormB.Close
MyProperty is still true.

4. Call ToggleMyProperty
Now MyProperty = false and I can see this by printing the value to the
console.

5. FormB.Show
Remember that MyProperty = false, but the PropertyGrid still shows the
value as true.

I've tried everything I can think of. I've called the Refresh method
on the PropertyGrid. I've set the PropertyGrid's SelectedObject to
null and back to the object. Nothing I've done so far has worked and
so I can only assume that it's just some dumba** mistake on my part.

It's almost like the PropertyGrid is "stuck" on the initial values.
Like I said, if I call the ToggleMyProperty method and then print the
results then I always get what I expect. Also, if I do this from
FormA...

MySingleton.GetInstance().MyProperty =
!MySingleton.GetInstance().MyProperty;

...then the PropertyGrid updates correctly. With that in mind, I have
a sneaking suspicion that the statement I'm using to set the
PropertyGrid's SelectedObject is at fault. I would just use
SelectedObject = MySingleton, but I can't since FormB has no idea that
MySingleton exists.

Any takers?

-Shuttermutt



Sat, 04 Jun 2005 07:39:33 GMT  
 Pleading for fresh eyes on my problem using a PropertyGrid with a Singleton
Hi there,

Ok, I quickly had a look. The code below should compile. It came down to
these factors though:

- Having formA confused matters a little - you don't need it to hold the
Singleton, a singleton exists whether it is on a form or not!
- You needed to call refresh on the property control. This updates itself to
reflect the state of the singleton.
- Ideally, the the Singleton should toggle it's own value, after all - it
does belong to it, so it should be responsible for changing it! A small
point though!

HTH

Tobin

public class Singleton

{

private static Singleton singleton = null;

private bool myProperty;

public static Singleton GetInstance() {

if(singleton == null) {

singleton = new Singleton();

Quote:
}

return singleton;

Quote:
}

private Singleton() {

this.myProperty = true;

Quote:
}

public bool MyProperty{

get { return this.myProperty; }

Quote:
}

public void ToggleMyProperty(){

myProperty = ! myProperty;

Console.WriteLine("Singleton property chainging to " +
myProperty.ToString() );

Quote:
}
}

public class FormB : Form {

PropertyGrid propertyGrid = new PropertyGrid();

Button b = new Button();

public static void Main(){

Application.Run( new FormB() );

Quote:
}

public FormB(){

b.Click += new EventHandler( HandleButtonClick );

propertyGrid.Dock = DockStyle.Fill;

b.Dock = DockStyle.Bottom;

b.Text = "Click Me!";

this.Controls.Add( propertyGrid );

this.Controls.Add( b );

this.propertyGrid.SelectedObject = Singleton.GetInstance();

Quote:
}

private void HandleButtonClick( object sender, EventArgs e){

Singleton.GetInstance().ToggleMyProperty();

propertyGrid.Refresh(); //this is crucial!!

Quote:
}
}



Sat, 04 Jun 2005 09:07:55 GMT  
 Pleading for fresh eyes on my problem using a PropertyGrid with a Singleton
Well, Tobin... it appears I've solved the problem as I was writing a
response to your post. Turns out that my problem marks yet another in a long
string of casting errors that I've made. Let's see what I was doing wrong
and two ways to fix it.

Here's the (non-working) code...

this.propertyGrid.SelectedObject = MyClass.GetInstance();

And here's how I fixed it...

this.propertyGrid.SelectedObject = (MyClass)MyClass.GetInstance();

Of course, I could have done this, too...

MyClass MyObject;
MyObject = MyClass.GetInstance();
this.propertyGrid.SelectedObject.MyObject;

Thanks for your response, Tobin! I'll only lose a few more hours to casting
errors before I remember!

-Shuttermutt


Quote:
> Hi there,

> Ok, I quickly had a look. The code below should compile. It came down to
> these factors though:

> - Having formA confused matters a little - you don't need it to hold the
> Singleton, a singleton exists whether it is on a form or not!
> - You needed to call refresh on the property control. This updates itself
to
> reflect the state of the singleton.
> - Ideally, the the Singleton should toggle it's own value, after all - it
> does belong to it, so it should be responsible for changing it! A small
> point though!

> HTH

> Tobin

> public class Singleton

> {

> private static Singleton singleton = null;

> private bool myProperty;

> public static Singleton GetInstance() {

> if(singleton == null) {

> singleton = new Singleton();

> }

> return singleton;

> }

> private Singleton() {

> this.myProperty = true;

> }

> public bool MyProperty{

> get { return this.myProperty; }

> }

> public void ToggleMyProperty(){

> myProperty = ! myProperty;

> Console.WriteLine("Singleton property chainging to " +
> myProperty.ToString() );

> }

> }

> public class FormB : Form {

> PropertyGrid propertyGrid = new PropertyGrid();

> Button b = new Button();

> public static void Main(){

> Application.Run( new FormB() );

> }

> public FormB(){

> b.Click += new EventHandler( HandleButtonClick );

> propertyGrid.Dock = DockStyle.Fill;

> b.Dock = DockStyle.Bottom;

> b.Text = "Click Me!";

> this.Controls.Add( propertyGrid );

> this.Controls.Add( b );

> this.propertyGrid.SelectedObject = Singleton.GetInstance();

> }

> private void HandleButtonClick( object sender, EventArgs e){

> Singleton.GetInstance().ToggleMyProperty();

> propertyGrid.Refresh(); //this is crucial!!

> }

> }



Sat, 04 Jun 2005 11:04:44 GMT  
 Pleading for fresh eyes on my problem using a PropertyGrid with a Singleton

Quote:

> Greets everyone! I've been trying to solve this problem for about 3
> hours now and I'm just coming up short and I'm keeping my fingers
> crossed that a fresh set of eyes and a new perspective will help.
> Here's the (very simplified) deal...

It seems you've solved your problem, but one slight suggestion:

<snip>

Quote:
> public class Singleton
> {
>    private static Singleton singleton = null;

>    public static Singleton GetInstance()
>    {
>            if(singleton == null)
>            {
>                    singleton = new Singleton();
>            }
>            return singleton;
>    }

This is not thread-safe - if two threads call GetInstance at a very
similar time, you could end up with two instances. You *could* use
synchronization here, but the easiest way round it is to change your
declaration of singleton to include initialization:

private static Singleton singleton = new Singleton();

and just make GetInstance return singleton.

(You might also want to consider making it a property rather than just a
method, but that's really just cosmetic.)

That's thread-safe and is still lazily instantiated as the initializer
won't be run until the class is initialized, which is done lazily.

--
Jon Skeet

If replying to the group, please do not mail me at the same time



Sat, 04 Jun 2005 17:52:09 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Populating a PropertyGrid using reflected types.

2. Singleton not a singleton?

3. ATL Singleton and Singleton Class also from C++

4. Using C# PropertyGrids

5. A problem about the PropertyGrid.

6. Singleton class factory using ROT???

7. play Fresh in MFC-based application

8. Fresh treeview

9. Fresh Teens Live....

10. VS7 compile error (fresh install)

11. Reference count problem in singleton container

12. duplicated Singleton instances problem...

 

 
Powered by phpBB® Forum Software