changing the default caption/id for an item in a collection editor?

J

Jiho Han

I have a custom control - deriving from WebControl - that contains a custom
collection property as the default property.
The collection implements IList and each item is also a custom control
deriving from Panel control.
I don't have a custom collection editor.

Whenever I add my item through the collection editor, the member name
generated by it are "myPanel1", "myPanel2", and so on where the the class
name is MyPanel. And that member name is then put in the codebehind like
so:

protected MyPanel myPanel1;
protected MyPanel myPanel2;

Is there a way to override this behavior? Also, I figured setting the ID
property on the item before it being added to the collection might do the
trick but it didn't. So now I have in my codebehind declarations like above
but in my HTML the thing is persisted like:

<cc:MyPanel Caption="MyPanel1" ID="MyPanel1"></cc:MyPanel>

And c# complains because it's case-sensitive.

Another thing that bothers me more is this -

My main control is derived from WebControl so ParseChildren(true) and
PersistChildren(false) are the default. ParseChild(true, "MyPanels")
actually since, I have the collection as the default property.

So my code looks like this:

[DesignSerializationVisibility(DesignSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty),
NotifyParentProperty(true)]
public MyPanelCollection MyPanels
{
get
{
if (_myPanels == null)
_myPanels = new MyPanelCollection(this);
return _myPanels;
}
}

It works. Maybe too well. Add 3 panels through the collection editor, it
results in the following HTML.

<cc:MyCustomControl ID="MyCustomControl1" runat="server">
<cc:MyPanel Caption="myPanel1" ID="myPanel1"></cc:MyPanel>
<cc:MyPanel Caption="myPanel2" ID="myPanel2"></cc:MyPanel>
<cc:MyPanel Caption="myPanel3" ID="myPanel3"></cc:MyPanel>
</cc:MyCustomControl>

That's fine, but at the same time, those 3 MyPanels are added as child
controls to my MyCustomControl1 and three of those statements get put into
my codebehind. I go to the HTML view, add a fourth MyPanel following all
conventions except for the number 4. I switch to the design view, open up
the collection editor and now all my members are listed as "TabPage" which
of course do not match any of the statements in my codebehind. And those
three statements are wiped out. I don't know if that's the reason. What
gives?

And I don't understand why my MyPanel controls are being added as child
controls in the first place. I don't add them in my code - actually I was
but then I commented out CreateChildControls. Isn't ParseChildren(true)
supposed to parse the nested content as properties? And so it correctly
parses the default collection and adds individual MyPanel items to the
collection correctly, but why are they added to MyCustomControl as child
controls? Did I confuse anyone or is it just me?

Help.
 
A

Alessandro Zifiglio

hi Jiho,
do you see these unwanted child panels in your toolbox as well ? Which ever
the case I think your child panels are added in your code behind because
your collections derieve from panel which in turn is a webcontrol.
Try specifying the following to your collection to hide it from the toolbox
and designtime, not sure if this is your case, however give it a try. I have
a hunch that you added the toolboxitem(false) attribute and forgot to set
the DesignTimeVisible to false as well ;P
[ToolboxItem(false),DesignTimeVisible(false)]


Jiho Han said:
I have a custom control - deriving from WebControl - that contains a custom
collection property as the default property.
The collection implements IList and each item is also a custom control
deriving from Panel control.
I don't have a custom collection editor.

Whenever I add my item through the collection editor, the member name
generated by it are "myPanel1", "myPanel2", and so on where the the class
name is MyPanel. And that member name is then put in the codebehind like
so:

protected MyPanel myPanel1;
protected MyPanel myPanel2;

Is there a way to override this behavior? Also, I figured setting the ID
property on the item before it being added to the collection might do the
trick but it didn't. So now I have in my codebehind declarations like above
but in my HTML the thing is persisted like:

<cc:MyPanel Caption="MyPanel1" ID="MyPanel1"></cc:MyPanel>

And c# complains because it's case-sensitive.

Another thing that bothers me more is this -

My main control is derived from WebControl so ParseChildren(true) and
PersistChildren(false) are the default. ParseChild(true, "MyPanels")
actually since, I have the collection as the default property.

So my code looks like this:

[DesignSerializationVisibility(DesignSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty),
NotifyParentProperty(true)]
public MyPanelCollection MyPanels
{
get
{
if (_myPanels == null)
_myPanels = new MyPanelCollection(this);
return _myPanels;
}
}

It works. Maybe too well. Add 3 panels through the collection editor, it
results in the following HTML.

<cc:MyCustomControl ID="MyCustomControl1" runat="server">
<cc:MyPanel Caption="myPanel1" ID="myPanel1"></cc:MyPanel>
<cc:MyPanel Caption="myPanel2" ID="myPanel2"></cc:MyPanel>
<cc:MyPanel Caption="myPanel3" ID="myPanel3"></cc:MyPanel>
</cc:MyCustomControl>

That's fine, but at the same time, those 3 MyPanels are added as child
controls to my MyCustomControl1 and three of those statements get put into
my codebehind. I go to the HTML view, add a fourth MyPanel following all
conventions except for the number 4. I switch to the design view, open up
the collection editor and now all my members are listed as "TabPage" which
of course do not match any of the statements in my codebehind. And those
three statements are wiped out. I don't know if that's the reason. What
gives?

And I don't understand why my MyPanel controls are being added as child
controls in the first place. I don't add them in my code - actually I was
but then I commented out CreateChildControls. Isn't ParseChildren(true)
supposed to parse the nested content as properties? And so it correctly
parses the default collection and adds individual MyPanel items to the
collection correctly, but why are they added to MyCustomControl as child
controls? Did I confuse anyone or is it just me?

Help.
 
J

Jiho Han

Thanks Alessandro for your reponse.

You're correct. I did set ToolBoxItem(false) but did not set
DesignTimeVisible(false) at the same time. However having done that, it
didn't change the outcome.
Ok, this is what I am trying to do. I want to add my custom control to the
form, edit it, add to its collection either via designer or in HTML but have
it not write out the collection item (panel) declaration statements in my
codebehind.

In pursuit of this functionality, I've tried to use ShouldCodeSerialize
method of the ControlDesigner class with no success. This stops it from
writing out to the codebehind but at the same time, it stops HTML changes to
take effect. I tried to attach a derived CodeDomSerializer to the control
with no success. It simply didn't seem to do anything.

One thing I've noticed is that whenever I tried to add any control type
through the collection editor, it writes out the declaration statments to my
codebehind class. When I derived my custom panel from Panel or Control, the
statements were there. When I derived from nothing - thus object - it did
not. I don't think it's the work of CollectionEditor per se. I've digging
around for a bit, and it simply depends on the fact whether the component
has a name or not. The name is not a property of the control but rather the
Site that is attached to a component by the designer. When the collection
editor creates the component, it asks the VS to create it via
CreateComponent method while in HTML mode, it does not and so there is no
Site property available, thus no Name. When there is no Name for a
component, VS does not write out the statement to the codebehind I guess
because it doesn't know what to name it :).

At this point, I am really confused as to what's really going on and am
losing patience. I just might change my Panel control so that it does not
derive from a Control. That way it won't automaticall be added. And I'll
just add the actual Panels in my CreateChildControls. I'll let you know how
that works out. This is only the beginning since after this, I am trying to
attach ReadWriteControlDesigner to my control so that the page developers
can drag and drop other controls onto it. As you may have guess I'm trying
to create a TabControl :) Page control uses TemplatedControlDesigner
however and I am still wondering how these two are different and which one
to use ultimately.

Thanks for reading. If any Microsoft guys are reading this, I'd really
appreciate some clarification.
Jiho

Alessandro Zifiglio said:
hi Jiho,
do you see these unwanted child panels in your toolbox as well ? Which ever
the case I think your child panels are added in your code behind because
your collections derieve from panel which in turn is a webcontrol.
Try specifying the following to your collection to hide it from the toolbox
and designtime, not sure if this is your case, however give it a try. I have
a hunch that you added the toolboxitem(false) attribute and forgot to set
the DesignTimeVisible to false as well ;P
[ToolboxItem(false),DesignTimeVisible(false)]


Jiho Han said:
I have a custom control - deriving from WebControl - that contains a custom
collection property as the default property.
The collection implements IList and each item is also a custom control
deriving from Panel control.
I don't have a custom collection editor.

Whenever I add my item through the collection editor, the member name
generated by it are "myPanel1", "myPanel2", and so on where the the class
name is MyPanel. And that member name is then put in the codebehind like
so:

protected MyPanel myPanel1;
protected MyPanel myPanel2;

Is there a way to override this behavior? Also, I figured setting the ID
property on the item before it being added to the collection might do the
trick but it didn't. So now I have in my codebehind declarations like above
but in my HTML the thing is persisted like:

<cc:MyPanel Caption="MyPanel1" ID="MyPanel1"></cc:MyPanel>

And c# complains because it's case-sensitive.

Another thing that bothers me more is this -

My main control is derived from WebControl so ParseChildren(true) and
PersistChildren(false) are the default. ParseChild(true, "MyPanels")
actually since, I have the collection as the default property.

So my code looks like this:

[DesignSerializationVisibility(DesignSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty),
NotifyParentProperty(true)]
public MyPanelCollection MyPanels
{
get
{
if (_myPanels == null)
_myPanels = new MyPanelCollection(this);
return _myPanels;
}
}

It works. Maybe too well. Add 3 panels through the collection editor, it
results in the following HTML.

<cc:MyCustomControl ID="MyCustomControl1" runat="server">
<cc:MyPanel Caption="myPanel1" ID="myPanel1"></cc:MyPanel>
<cc:MyPanel Caption="myPanel2" ID="myPanel2"></cc:MyPanel>
<cc:MyPanel Caption="myPanel3" ID="myPanel3"></cc:MyPanel>
</cc:MyCustomControl>

That's fine, but at the same time, those 3 MyPanels are added as child
controls to my MyCustomControl1 and three of those statements get put into
my codebehind. I go to the HTML view, add a fourth MyPanel following all
conventions except for the number 4. I switch to the design view, open up
the collection editor and now all my members are listed as "TabPage" which
of course do not match any of the statements in my codebehind. And those
three statements are wiped out. I don't know if that's the reason. What
gives?

And I don't understand why my MyPanel controls are being added as child
controls in the first place. I don't add them in my code - actually I was
but then I commented out CreateChildControls. Isn't ParseChildren(true)
supposed to parse the nested content as properties? And so it correctly
parses the default collection and adds individual MyPanel items to the
collection correctly, but why are they added to MyCustomControl as child
controls? Did I confuse anyone or is it just me?

Help.
 
A

Alessandro Zifiglio

Jiho, just a thought but if this is not working for you, and y our already
going to make changes to your control, try looking at the source code thats
available with the IE web controls. Theres a TabStrip control in there. They
are not using panels but I'm sure you could use some implementation
techniques, ideas from them.
Jiho Han said:
Thanks Alessandro for your reponse.

You're correct. I did set ToolBoxItem(false) but did not set
DesignTimeVisible(false) at the same time. However having done that, it
didn't change the outcome.
Ok, this is what I am trying to do. I want to add my custom control to the
form, edit it, add to its collection either via designer or in HTML but have
it not write out the collection item (panel) declaration statements in my
codebehind.

In pursuit of this functionality, I've tried to use ShouldCodeSerialize
method of the ControlDesigner class with no success. This stops it from
writing out to the codebehind but at the same time, it stops HTML changes to
take effect. I tried to attach a derived CodeDomSerializer to the control
with no success. It simply didn't seem to do anything.

One thing I've noticed is that whenever I tried to add any control type
through the collection editor, it writes out the declaration statments to my
codebehind class. When I derived my custom panel from Panel or Control, the
statements were there. When I derived from nothing - thus object - it did
not. I don't think it's the work of CollectionEditor per se. I've digging
around for a bit, and it simply depends on the fact whether the component
has a name or not. The name is not a property of the control but rather the
Site that is attached to a component by the designer. When the collection
editor creates the component, it asks the VS to create it via
CreateComponent method while in HTML mode, it does not and so there is no
Site property available, thus no Name. When there is no Name for a
component, VS does not write out the statement to the codebehind I guess
because it doesn't know what to name it :).

At this point, I am really confused as to what's really going on and am
losing patience. I just might change my Panel control so that it does not
derive from a Control. That way it won't automaticall be added. And I'll
just add the actual Panels in my CreateChildControls. I'll let you know how
that works out. This is only the beginning since after this, I am trying to
attach ReadWriteControlDesigner to my control so that the page developers
can drag and drop other controls onto it. As you may have guess I'm trying
to create a TabControl :) Page control uses TemplatedControlDesigner
however and I am still wondering how these two are different and which one
to use ultimately.

Thanks for reading. If any Microsoft guys are reading this, I'd really
appreciate some clarification.
Jiho

Alessandro Zifiglio said:
hi Jiho,
do you see these unwanted child panels in your toolbox as well ? Which ever
the case I think your child panels are added in your code behind because
your collections derieve from panel which in turn is a webcontrol.
Try specifying the following to your collection to hide it from the toolbox
and designtime, not sure if this is your case, however give it a try. I have
a hunch that you added the toolboxitem(false) attribute and forgot to set
the DesignTimeVisible to false as well ;P
[ToolboxItem(false),DesignTimeVisible(false)]


Jiho Han said:
I have a custom control - deriving from WebControl - that contains a custom
collection property as the default property.
The collection implements IList and each item is also a custom control
deriving from Panel control.
I don't have a custom collection editor.

Whenever I add my item through the collection editor, the member name
generated by it are "myPanel1", "myPanel2", and so on where the the class
name is MyPanel. And that member name is then put in the codebehind like
so:

protected MyPanel myPanel1;
protected MyPanel myPanel2;

Is there a way to override this behavior? Also, I figured setting the ID
property on the item before it being added to the collection might do the
trick but it didn't. So now I have in my codebehind declarations like above
but in my HTML the thing is persisted like:

<cc:MyPanel Caption="MyPanel1" ID="MyPanel1"></cc:MyPanel>

And c# complains because it's case-sensitive.

Another thing that bothers me more is this -

My main control is derived from WebControl so ParseChildren(true) and
PersistChildren(false) are the default. ParseChild(true, "MyPanels")
actually since, I have the collection as the default property.

So my code looks like this:

[DesignSerializationVisibility(DesignSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty),
NotifyParentProperty(true)]
public MyPanelCollection MyPanels
{
get
{
if (_myPanels == null)
_myPanels = new MyPanelCollection(this);
return _myPanels;
}
}

It works. Maybe too well. Add 3 panels through the collection
editor,
open
 
J

Jiho Han

Thanks for keeping up Alessandro.

Really, sometimes solutions are in the simplest places you've never thought
to look because it's so simple.
What I ended up doing is that I went back to my original design where my
tabs are derived from Panel - it really doesn't matter if it is any other
Control though - and created a custom collection editor and overrode the
method CreateInstance. In it I create a new instance of the tab panel and
return it. This way there is no site for the control and it behaves
identically as when the control is parsed from HTML. I really didn't want
those declaration statements in my codebehind for each tab anyway, so it's
working out perfectly.

BTW, do you know if they have sources available for those IE web controls?
Probably not eh?
Thanks

Alessandro Zifiglio said:
Jiho, just a thought but if this is not working for you, and y our already
going to make changes to your control, try looking at the source code thats
available with the IE web controls. Theres a TabStrip control in there. They
are not using panels but I'm sure you could use some implementation
techniques, ideas from them.
Jiho Han said:
Thanks Alessandro for your reponse.

You're correct. I did set ToolBoxItem(false) but did not set
DesignTimeVisible(false) at the same time. However having done that, it
didn't change the outcome.
Ok, this is what I am trying to do. I want to add my custom control to the
form, edit it, add to its collection either via designer or in HTML but have
it not write out the collection item (panel) declaration statements in my
codebehind.

In pursuit of this functionality, I've tried to use ShouldCodeSerialize
method of the ControlDesigner class with no success. This stops it from
writing out to the codebehind but at the same time, it stops HTML
changes
to
take effect. I tried to attach a derived CodeDomSerializer to the control
with no success. It simply didn't seem to do anything.

One thing I've noticed is that whenever I tried to add any control type
through the collection editor, it writes out the declaration statments
to
my
codebehind class. When I derived my custom panel from Panel or Control, the
statements were there. When I derived from nothing - thus object - it did
not. I don't think it's the work of CollectionEditor per se. I've digging
around for a bit, and it simply depends on the fact whether the component
has a name or not. The name is not a property of the control but rather the
Site that is attached to a component by the designer. When the collection
editor creates the component, it asks the VS to create it via
CreateComponent method while in HTML mode, it does not and so there is no
Site property available, thus no Name. When there is no Name for a
component, VS does not write out the statement to the codebehind I guess
because it doesn't know what to name it :).

At this point, I am really confused as to what's really going on and am
losing patience. I just might change my Panel control so that it does not
derive from a Control. That way it won't automaticall be added. And I'll
just add the actual Panels in my CreateChildControls. I'll let you know how
that works out. This is only the beginning since after this, I am
trying
to
attach ReadWriteControlDesigner to my control so that the page developers
can drag and drop other controls onto it. As you may have guess I'm trying
to create a TabControl :) Page control uses TemplatedControlDesigner
however and I am still wondering how these two are different and which one
to use ultimately.

Thanks for reading. If any Microsoft guys are reading this, I'd really
appreciate some clarification.
Jiho

Alessandro Zifiglio said:
hi Jiho,
do you see these unwanted child panels in your toolbox as well ? Which ever
the case I think your child panels are added in your code behind because
your collections derieve from panel which in turn is a webcontrol.
Try specifying the following to your collection to hide it from the toolbox
and designtime, not sure if this is your case, however give it a try.
I
have
a hunch that you added the toolboxitem(false) attribute and forgot to set
the DesignTimeVisible to false as well ;P
[ToolboxItem(false),DesignTimeVisible(false)]


I have a custom control - deriving from WebControl - that contains a
custom
collection property as the default property.
The collection implements IList and each item is also a custom control
deriving from Panel control.
I don't have a custom collection editor.

Whenever I add my item through the collection editor, the member name
generated by it are "myPanel1", "myPanel2", and so on where the the class
name is MyPanel. And that member name is then put in the codebehind like
so:

protected MyPanel myPanel1;
protected MyPanel myPanel2;

Is there a way to override this behavior? Also, I figured setting
the
ID
property on the item before it being added to the collection might
do
the
trick but it didn't. So now I have in my codebehind declarations like
above
but in my HTML the thing is persisted like:

<cc:MyPanel Caption="MyPanel1" ID="MyPanel1"></cc:MyPanel>

And c# complains because it's case-sensitive.

Another thing that bothers me more is this -

My main control is derived from WebControl so ParseChildren(true) and
PersistChildren(false) are the default. ParseChild(true, "MyPanels")
actually since, I have the collection as the default property.

So my code looks like this:

[DesignSerializationVisibility(DesignSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty),
NotifyParentProperty(true)]
public MyPanelCollection MyPanels
{
get
{
if (_myPanels == null)
_myPanels = new MyPanelCollection(this);
return _myPanels;
}
}

It works. Maybe too well. Add 3 panels through the collection
editor,
it
results in the following HTML.

<cc:MyCustomControl ID="MyCustomControl1" runat="server">
<cc:MyPanel Caption="myPanel1" ID="myPanel1"></cc:MyPanel>
<cc:MyPanel Caption="myPanel2" ID="myPanel2"></cc:MyPanel>
<cc:MyPanel Caption="myPanel3" ID="myPanel3"></cc:MyPanel>
</cc:MyCustomControl>

That's fine, but at the same time, those 3 MyPanels are added as child
controls to my MyCustomControl1 and three of those statements get
put
into
my codebehind. I go to the HTML view, add a fourth MyPanel
following
all
conventions except for the number 4. I switch to the design view,
open
up
the collection editor and now all my members are listed as "TabPage" which
of course do not match any of the statements in my codebehind. And those
three statements are wiped out. I don't know if that's the reason. What
gives?

And I don't understand why my MyPanel controls are being added as child
controls in the first place. I don't add them in my code - actually
I
was
but then I commented out CreateChildControls. Isn't ParseChildren(true)
supposed to parse the nested content as properties? And so it correctly
parses the default collection and adds individual MyPanel items to the
collection correctly, but why are they added to MyCustomControl as child
controls? Did I confuse anyone or is it just me?

Help.
 
J

Jiho Han

Never mind, it does come with the source. I see that the tab functionality
is implemented as two separate controls a tabstrip and multipage, which is
ok I guess but the multipage control doesn't support drag and drop of other
controls which is unfortunate...

Jiho Han said:
Thanks for keeping up Alessandro.

Really, sometimes solutions are in the simplest places you've never thought
to look because it's so simple.
What I ended up doing is that I went back to my original design where my
tabs are derived from Panel - it really doesn't matter if it is any other
Control though - and created a custom collection editor and overrode the
method CreateInstance. In it I create a new instance of the tab panel and
return it. This way there is no site for the control and it behaves
identically as when the control is parsed from HTML. I really didn't want
those declaration statements in my codebehind for each tab anyway, so it's
working out perfectly.

BTW, do you know if they have sources available for those IE web controls?
Probably not eh?
Thanks

Alessandro Zifiglio said:
Jiho, just a thought but if this is not working for you, and y our already
going to make changes to your control, try looking at the source code thats
available with the IE web controls. Theres a TabStrip control in there. They
are not using panels but I'm sure you could use some implementation
techniques, ideas from them.
to
the but
have changes to Control,
the rather
the know
how trying
try.
I
have
a hunch that you added the toolboxitem(false) attribute and forgot
to
set
the DesignTimeVisible to false as well ;P
[ToolboxItem(false),DesignTimeVisible(false)]


I have a custom control - deriving from WebControl - that contains a
custom
collection property as the default property.
The collection implements IList and each item is also a custom control
deriving from Panel control.
I don't have a custom collection editor.

Whenever I add my item through the collection editor, the member name
generated by it are "myPanel1", "myPanel2", and so on where the the
class
name is MyPanel. And that member name is then put in the codebehind
like
so:

protected MyPanel myPanel1;
protected MyPanel myPanel2;

Is there a way to override this behavior? Also, I figured setting the
ID
property on the item before it being added to the collection might do
the
trick but it didn't. So now I have in my codebehind declarations like
above
but in my HTML the thing is persisted like:

<cc:MyPanel Caption="MyPanel1" ID="MyPanel1"></cc:MyPanel>

And c# complains because it's case-sensitive.

Another thing that bothers me more is this -

My main control is derived from WebControl so ParseChildren(true) and
PersistChildren(false) are the default. ParseChild(true, "MyPanels")
actually since, I have the collection as the default property.

So my code looks like this:

[DesignSerializationVisibility(DesignSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty),
NotifyParentProperty(true)]
public MyPanelCollection MyPanels
{
get
{
if (_myPanels == null)
_myPanels = new MyPanelCollection(this);
return _myPanels;
}
}

It works. Maybe too well. Add 3 panels through the collection editor,
it
results in the following HTML.

<cc:MyCustomControl ID="MyCustomControl1" runat="server">
<cc:MyPanel Caption="myPanel1" ID="myPanel1"></cc:MyPanel>
<cc:MyPanel Caption="myPanel2" ID="myPanel2"></cc:MyPanel>
<cc:MyPanel Caption="myPanel3" ID="myPanel3"></cc:MyPanel>
</cc:MyCustomControl>

That's fine, but at the same time, those 3 MyPanels are added as child
controls to my MyCustomControl1 and three of those statements get put
into
my codebehind. I go to the HTML view, add a fourth MyPanel following
all
conventions except for the number 4. I switch to the design view, open
up
the collection editor and now all my members are listed as "TabPage"
which
of course do not match any of the statements in my codebehind. And
those
three statements are wiped out. I don't know if that's the reason.
What
gives?

And I don't understand why my MyPanel controls are being added as child
controls in the first place. I don't add them in my code -
actually
 
A

Alessandro Zifiglio

Yeah, combing the tabstrip with the multipage gives you the behaviour your
trying to achieve with your custom control, however you've managed to get
your control working and resolved. Most times when you dig too deep only you
the author can come up with the solutions and someone else will only slow
you down. This is one of those cases ;P

Glad you solved Jiho ;)
Jiho Han said:
Never mind, it does come with the source. I see that the tab functionality
is implemented as two separate controls a tabstrip and multipage, which is
ok I guess but the multipage control doesn't support drag and drop of other
controls which is unfortunate...

Jiho Han said:
Thanks for keeping up Alessandro.

Really, sometimes solutions are in the simplest places you've never thought
to look because it's so simple.
What I ended up doing is that I went back to my original design where my
tabs are derived from Panel - it really doesn't matter if it is any other
Control though - and created a custom collection editor and overrode the
method CreateInstance. In it I create a new instance of the tab panel and
return it. This way there is no site for the control and it behaves
identically as when the control is parsed from HTML. I really didn't want
those declaration statements in my codebehind for each tab anyway, so it's
working out perfectly.

BTW, do you know if they have sources available for those IE web controls?
Probably not eh?
Thanks

there.
They
that,
it
didn't change the outcome.
Ok, this is what I am trying to do. I want to add my custom control to
the
form, edit it, add to its collection either via designer or in HTML but
have
it not write out the collection item (panel) declaration statements
in
my
codebehind.

In pursuit of this functionality, I've tried to use ShouldCodeSerialize
method of the ControlDesigner class with no success. This stops it from
writing out to the codebehind but at the same time, it stops HTML changes
to
take effect. I tried to attach a derived CodeDomSerializer to the control
with no success. It simply didn't seem to do anything.

One thing I've noticed is that whenever I tried to add any control type
through the collection editor, it writes out the declaration
statments
to
my
codebehind class. When I derived my custom panel from Panel or Control,
the
statements were there. When I derived from nothing - thus object -
it
did
not. I don't think it's the work of CollectionEditor per se. I've
digging
around for a bit, and it simply depends on the fact whether the component
has a name or not. The name is not a property of the control but rather
the
Site that is attached to a component by the designer. When the collection
editor creates the component, it asks the VS to create it via
CreateComponent method while in HTML mode, it does not and so there
is
no
Site property available, thus no Name. When there is no Name for a
component, VS does not write out the statement to the codebehind I guess
because it doesn't know what to name it :).

At this point, I am really confused as to what's really going on and am
losing patience. I just might change my Panel control so that it
does
not
derive from a Control. That way it won't automaticall be added.
And
I'll
just add the actual Panels in my CreateChildControls. I'll let you know
how
that works out. This is only the beginning since after this, I am trying
to
attach ReadWriteControlDesigner to my control so that the page developers
can drag and drop other controls onto it. As you may have guess I'm
trying
to create a TabControl :) Page control uses TemplatedControlDesigner
however and I am still wondering how these two are different and
which
one
to use ultimately.

Thanks for reading. If any Microsoft guys are reading this, I'd really
appreciate some clarification.
Jiho

message
hi Jiho,
do you see these unwanted child panels in your toolbox as well ? Which
ever
the case I think your child panels are added in your code behind because
your collections derieve from panel which in turn is a webcontrol.
Try specifying the following to your collection to hide it from the
toolbox
and designtime, not sure if this is your case, however give it a
try.
I
have
a hunch that you added the toolboxitem(false) attribute and forgot to
set
the DesignTimeVisible to false as well ;P
[ToolboxItem(false),DesignTimeVisible(false)]


I have a custom control - deriving from WebControl - that
contains
a
custom
collection property as the default property.
The collection implements IList and each item is also a custom control
deriving from Panel control.
I don't have a custom collection editor.

Whenever I add my item through the collection editor, the member name
generated by it are "myPanel1", "myPanel2", and so on where the the
class
name is MyPanel. And that member name is then put in the codebehind
like
so:

protected MyPanel myPanel1;
protected MyPanel myPanel2;

Is there a way to override this behavior? Also, I figured
setting
the
ID
property on the item before it being added to the collection
might
do
the
trick but it didn't. So now I have in my codebehind
declarations
like
above
but in my HTML the thing is persisted like:

<cc:MyPanel Caption="MyPanel1" ID="MyPanel1"></cc:MyPanel>

And c# complains because it's case-sensitive.

Another thing that bothers me more is this -

My main control is derived from WebControl so
ParseChildren(true)
and
PersistChildren(false) are the default. ParseChild(true, "MyPanels")
actually since, I have the collection as the default property.

So my code looks like this:

[DesignSerializationVisibility(DesignSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty),
NotifyParentProperty(true)]
public MyPanelCollection MyPanels
{
get
{
if (_myPanels == null)
_myPanels = new MyPanelCollection(this);
return _myPanels;
}
}

It works. Maybe too well. Add 3 panels through the collection
editor,
it
results in the following HTML.

<cc:MyCustomControl ID="MyCustomControl1" runat="server">
<cc:MyPanel Caption="myPanel1"
ID="myPanel1"> said:
<cc:MyPanel Caption="myPanel2"
ID="myPanel2"> said:
<cc:MyPanel Caption="myPanel3"
ID="myPanel3"> said:
</cc:MyCustomControl>

That's fine, but at the same time, those 3 MyPanels are added as child
controls to my MyCustomControl1 and three of those statements
get
put
into
my codebehind. I go to the HTML view, add a fourth MyPanel following
all
conventions except for the number 4. I switch to the design view,
open
up
the collection editor and now all my members are listed as "TabPage"
which
of course do not match any of the statements in my codebehind. And
those
three statements are wiped out. I don't know if that's the reason.
What
gives?

And I don't understand why my MyPanel controls are being added as
child
controls in the first place. I don't add them in my code -
actually
I
was
but then I commented out CreateChildControls. Isn't
ParseChildren(true)
supposed to parse the nested content as properties? And so it
correctly
parses the default collection and adds individual MyPanel items
to
the
collection correctly, but why are they added to MyCustomControl as
child
controls? Did I confuse anyone or is it just me?

Help.
 
A

Alessandro Zifiglio

almost forgot. If your looking for drag and drop, and your control is a
templated control then go ahead and derive from the
TemplatedControlDesigner. If you have used the datalist control then you
will notice that you are able to drag and drop controls into its various
templates. This is the designer it uses, or atleast i think ;P
Its the same designer I use in my control too and it works great. I havent
had a chance to mess with the readwriteControlDesigner but in the docs it
says if you dont have templates and still want drag and drop this is the one
to use. Theres a good non-working example on MSDN for the
templatedControlDesigner --It will not run for you as is without you having
to make changes to some of the code in the sample and debugging it but it
does showcases most of the features and implementation. Nice sample but very
buggy code. ;P
http://msdn.microsoft.com/library/d...conwebformsdataboundcontroldesignersample.asp


Alessandro Zifiglio said:
Yeah, combing the tabstrip with the multipage gives you the behaviour your
trying to achieve with your custom control, however you've managed to get
your control working and resolved. Most times when you dig too deep only you
the author can come up with the solutions and someone else will only slow
you down. This is one of those cases ;P

Glad you solved Jiho ;)
Jiho Han said:
Never mind, it does come with the source. I see that the tab functionality
is implemented as two separate controls a tabstrip and multipage, which is
ok I guess but the multipage control doesn't support drag and drop of other
controls which is unfortunate...

that, control
to HTML
but
statements
in it
from
object -
it there
is
no
Site property available, thus no Name. When there is no Name for a
component, VS does not write out the statement to the codebehind I guess
because it doesn't know what to name it :).

At this point, I am really confused as to what's really going on
and
am
losing patience. I just might change my Panel control so that it does
not
derive from a Control. That way it won't automaticall be added. And
I'll
just add the actual Panels in my CreateChildControls. I'll let
you
know
how
that works out. This is only the beginning since after this, I am
trying
to
attach ReadWriteControlDesigner to my control so that the page
developers
can drag and drop other controls onto it. As you may have guess I'm
trying
to create a TabControl :) Page control uses TemplatedControlDesigner
however and I am still wondering how these two are different and which
one
to use ultimately.

Thanks for reading. If any Microsoft guys are reading this, I'd really
appreciate some clarification.
Jiho

"Alessandro Zifiglio" <[email protected]>
wrote
in
message
hi Jiho,
do you see these unwanted child panels in your toolbox as well ? Which
ever
the case I think your child panels are added in your code behind
because
your collections derieve from panel which in turn is a webcontrol.
Try specifying the following to your collection to hide it from the
toolbox
and designtime, not sure if this is your case, however give it a try.
I
have
a hunch that you added the toolboxitem(false) attribute and
forgot
to
set
the DesignTimeVisible to false as well ;P
[ToolboxItem(false),DesignTimeVisible(false)]


I have a custom control - deriving from WebControl - that
contains
a
custom
collection property as the default property.
The collection implements IList and each item is also a custom
control
deriving from Panel control.
I don't have a custom collection editor.

Whenever I add my item through the collection editor, the member
name
generated by it are "myPanel1", "myPanel2", and so on where
the
the
class
name is MyPanel. And that member name is then put in the codebehind
like
so:

protected MyPanel myPanel1;
protected MyPanel myPanel2;

Is there a way to override this behavior? Also, I figured setting
the
ID
property on the item before it being added to the collection might
do
the
trick but it didn't. So now I have in my codebehind declarations
like
above
but in my HTML the thing is persisted like:

<cc:MyPanel Caption="MyPanel1" ID="MyPanel1"></cc:MyPanel>

And c# complains because it's case-sensitive.

Another thing that bothers me more is this -

My main control is derived from WebControl so ParseChildren(true)
and
PersistChildren(false) are the default. ParseChild(true,
"MyPanels")
actually since, I have the collection as the default property.

So my code looks like this:


[DesignSerializationVisibility(DesignSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty),
NotifyParentProperty(true)]
public MyPanelCollection MyPanels
{
get
{
if (_myPanels == null)
_myPanels = new MyPanelCollection(this);
return _myPanels;
}
}

It works. Maybe too well. Add 3 panels through the collection
editor,
it
results in the following HTML.

<cc:MyCustomControl ID="MyCustomControl1" runat="server">
<cc:MyPanel Caption="myPanel1"
ID="myPanel1"> said:
<cc:MyPanel Caption="myPanel2"
ID="myPanel2"> said:
<cc:MyPanel Caption="myPanel3"
ID="myPanel3"> said:
</cc:MyCustomControl>

That's fine, but at the same time, those 3 MyPanels are added as
child
controls to my MyCustomControl1 and three of those statements get
put
into
my codebehind. I go to the HTML view, add a fourth MyPanel
following
all
conventions except for the number 4. I switch to the design view,
open
up
the collection editor and now all my members are listed as "TabPage"
which
of course do not match any of the statements in my codebehind. And
those
three statements are wiped out. I don't know if that's the reason.
What
gives?

And I don't understand why my MyPanel controls are being added as
child
controls in the first place. I don't add them in my code - actually
I
was
but then I commented out CreateChildControls. Isn't
ParseChildren(true)
supposed to parse the nested content as properties? And so it
correctly
parses the default collection and adds individual MyPanel
items
MyCustomControl
 

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

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top