Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / Design Time / November 2004

Tip: Looking for answers? Try searching our database.

IExtenderProvider with DesignOnly property.  An error?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
DRaiko - 29 Oct 2004 11:25 GMT
Hello Group,

It looks like an error.
To reproduce, create a simple ExtenderProvider component:

    [ProvideProperty( "Tttt", typeof( IComponent))]
    public class TestProvider : System.ComponentModel.Component, IExtenderProvider{
        private Hashtable    _hashTable;

        public TestProvider() {
            _hashTable = new Hashtable();
        }

        public bool CanExtend( object extendee) {
            return true;
        }
        [DesignOnly( true)]
        public string GetTttt( IComponent ctl){
            return (string)_hashTable[ ctl];
        }
        [DesignOnly( true)]
        public void SetTttt( IComponent ctl, string value){
            if( _hashTable.Contains( ctl))
                _hashTable[ ctl] = value;
            else
                _hashTable.Add( ctl, value);
        }
    }
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Just 20 lines. And it is enough to reproduce a misterious effect.
Throw a TextBox, this component and another TextBox on an empty form.
Exactly in that order! Set the property "Tttt" in textBox1 and in textBox2.
You can change them, undo and redo. This means, that they can be serialzed
and properly deserialized.
Save and close the project.
When you open it again, youll find the Tttt property in textBox1 empty.
It has the correct value in the .resx file but this value is not propagated
to the textbox. Why? The value in the textBox2 is OK. The only difference
between them is the creation order. You can remove the existing instance
of testProvider and create a new one. And a label, that is thus "younger"
than the provider component. Younger components have respect to the provider
and deserialze values. The senior ones ignore it!

If the project containing the provider component is in debug mode, you can
see, that no attempt is even done to set the Tttt property for those
components. Should be done by
CodeDomSerializer.DeserializePropertiesFromResources().

An error? By design? or both?
Am i doing something wrong (except wanting to use extended desing only
properties)?
Anybody have an explanation?

Thanks,
Dima.
DRaiko - 02 Nov 2004 10:25 GMT
Hi,

i guess i know the answer. It looks really as an error in VS.

First another experiment.
We all know that all Components are created at runtime by
InitializeComponents() and its first lines look like
   "this.comp = new CompType()".
I suppose that the Deserializer creates components in design time
in the same order.
If you change the order of these lines, you can see that each
extendee can deserialize only the DesignOnly properties that are defined
in extender providers created BEFORE it is created.

Here is an explanation of this effect.
All this applies only to desing only properties.
The set of the deserializable (and all other) properties is defined by
the PropertyDescrirtorCollection. This collection (i suppose) is created
for each component at the moment the component (extendee in this case)
is created. But the extended properties can be detected only if the extender
is already created. Those extenders that are created later are simply not
visible at this moment and can not be considered.

When property values are read from the .resx file the deserializer
sees all values but does not see all properties and does not know what
to do with the values that do not correspond to any known property.
The PropertyDescrirtorCollection is completed by VS at some moment later,
but deserialization is already over.

Thus: The extender must be created before the extendee is created.

Even if you change the order of lines in InitalizeComponents() manually,
there are still some problems.

(1) It is not possible to deserialize design-only extended properties
for the form itself (a form is a component and can be extended like any
other component). The reason is that any component on the form can be
created before the form is created.
The only way is to create a form with an extender instance on it and to
inherit from this form. Then the inherited form will be created when the
extender already exists. Rather inflexible.

(2) If two (or more) extenders extend each other they will fail no metter
what you try. (Extender_1 must be created before Extender_2, but Extender_2
must be created before Extender_1. Difficult to implement.) Well, I agree,
this scenario may look too exotic at first glance, but it would be nice
to save relationships between components this way.

Corrections? comments?

Thanks,
D.Raiko.

> Hello Group,
>
[quoted text clipped - 52 lines]
> Thanks,
> Dima.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.