Setting Inner Tag Content at Design Time programmatically

N

Nathaniel Greene

I am creating a web control. At design time I would like the designer to
inspect the control being hosted, to see if there is any inner content and if
there isn't then programmatically set the server control's markup.
for example <My:Control runat="server"></My:Control> would be changed to
<My:Control runat="server">Some markup</My:Control>
if SetEditableDesignerRegionContent is called by the designer the markup is
changed.
If I call it myself, however it's not changed. The same appears to be true
for Tag.SetContent and almost every other imaginable sample I've seen on the
web.

I have to assume that for a very basic procedure that I am simply missing
something. Tag.SetContent seems to do what i need it to do, except it won't
work if I call it.

Any tips?
 
W

Walter Wang [MSFT]

Hi Nathaniel,

Based on my understanding, you have a custom server control which has
ParseChildrenAttribute set to false and PersistChildrenAttribute set to
true:

[ParseChildren(false), PersistChildren(true)]
public class Class1 : WebControl
{
}

This will let user add content inside the control tag:

<cc1:Class1 ID="Class1_1" runat="server">
test
</cc1:Class1>

The objective is to add this default content when user didn't provide one.
Please feel free to let me know if I've misunderstood anything.


Currently I'm still researching on it and I will get back to you as soon as
possible. Thank you for your patience and understanding.


Sincerely,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications. If you are using Outlook Express, please make sure you clear the
check box "Tools/Options/Read: Get 300 headers at a time" to see your reply
promptly.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
W

Walter Wang [MSFT]

Hi Nathaniel,

To provide a default content in the inner tag, you need to create your own
control designer and override the method GetPersistenceContent():

public class Class1Designer : ControlDesigner
{
public override string GetPersistenceContent()
{
return "default content";
}
}

[ParseChildren(false), PersistChildren(true),
Designer(typeof(Class1Designer))]
public class Class1 : WebControl
{
}


Note this only works if the control is drag&dropped from toolbox to the
designer surface. If the control is manually written or dropped to the
source view, the default content will not be used. Also, when you dropped
the control to the designer surface, you need to refresh (menu
view/refresh, or right-click and select refresh) to see the default
content, but the source view actually already has the default content.

Let me know if you have any questions.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
N

Nathaniel Greene

That is not really what I want. Im looking for a way to set this when ever
the designer initializes and determines that there is no inner content.

The reason for this is because there are many issues, such as recently due
to Microsofts SP1 for VS2k5 update I can no longer drag and drop my custom
web controls from the toolbox), that will prevent a user from being able to
drag and drop. Also a user may wish to reset the content to default and in
both situations the Designer has to be able to set the Inner Content. I
cannot believe that something that Visual studio does all the time is not
capable of being user invoked from the designer.
 
N

Nathaniel Greene

Any updates?

Nathaniel Greene said:
That is not really what I want. Im looking for a way to set this when ever
the designer initializes and determines that there is no inner content.

The reason for this is because there are many issues, such as recently due
to Microsofts SP1 for VS2k5 update I can no longer drag and drop my custom
web controls from the toolbox), that will prevent a user from being able to
drag and drop. Also a user may wish to reset the content to default and in
both situations the Designer has to be able to set the Inner Content. I
cannot believe that something that Visual studio does all the time is not
capable of being user invoked from the designer.

Walter Wang said:
Hi Nathaniel,

To provide a default content in the inner tag, you need to create your own
control designer and override the method GetPersistenceContent():

public class Class1Designer : ControlDesigner
{
public override string GetPersistenceContent()
{
return "default content";
}
}

[ParseChildren(false), PersistChildren(true),
Designer(typeof(Class1Designer))]
public class Class1 : WebControl
{
}


Note this only works if the control is drag&dropped from toolbox to the
designer surface. If the control is manually written or dropped to the
source view, the default content will not be used. Also, when you dropped
the control to the designer surface, you need to refresh (menu
view/refresh, or right-click and select refresh) to see the default
content, but the source view actually already has the default content.

Let me know if you have any questions.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
W

Walter Wang [MSFT]

Hi Nathaniel,

Sorry for late reply. I was discussing your question with product team to
see if there're any other approaches.

In VS2005 the ControlDesigners effectively are only running while in design
view. That's why the GetPersistenceContent() only is effective when the
control is dropped on the designer surface. There're are other ways of
customizing the content of a control when it's drag/dropped such as using
the ToolboxDataAttribute. However this also only is effective when the
control gets first dropped.

Would you please tell me about your requirement? I think setting the
default initial value will be better for user experience. I mean, if I'm
the user and I removed the content and later found the content is filled
with other content again, I will be surprised.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
W

Walter Wang [MSFT]

Hi Nathaniel,

If you could describe your specific requirements detailly, we may find
other approach for your objective. Thanks.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
N

Nathaniel Greene

The control could most similary be compared to the "LoginView" that is part
of the asp.net web parts.
The control should be pre-populated with markup extracted from our
templates. The user has to be able to customize the content however, the user
should be able to reset the contents to the default template. Also, the
control has to be able to be populated if the user types the control manually
because he is unable to drag and drop.

I can't believe that all of ms's designers can do this. This is the basis
for everything, such as an <asp:ListItem's ListItem editing. adding columns
to a datagrid.
There has to be some flag or method that tells the designer to serialize the
content now because all of ms's controls can do it.
 
W

Walter Wang [MSFT]

Hi Nathaniel,

It seems I may have misunderstood your question at the very beginning. Are
you referring to Region-based Editing in ASP.NET Designer support? If this
is the case, you can find an example here:

#Panel Container with Styled and Region-based - The Code Project - ASP.NET
http://www.codeproject.com/useritems/shSimplePanel.asp


Regarding "<asp:ListItem's ListItem editing", I believe you're referring to
the CollectionEditor:

#Collection Editor Example
http://msdn2.microsoft.com/en-us/library/9zky1t4k.aspx


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
N

Nathaniel Greene

Yes I've already seen that example but no that doesn't do what I want it to
do.
Yes part of the region is going to be editable, but I've already
accomplished this.

What I am trying to do is this.

I have a control <my:pagesView></my:pagesView>
When a user drags it from the toolbox or types <my:pagesView and switches to
the designer
there is no content in there. The Designer checks to see if there is any
content. If there is no content it grabs the default template that shows up
here and sticks it in here. ( This is what I'm trying to do).

The user then makes edits to the content. Then he decides to reset the
template because he made a mistake. So he clicks a DesignerVerb link that
resets the content to the template default.

I listed the other items for reference because, they can do what I can't
seem to do.
When you edit a collection in an Design Time, for example, adding multiple
ListItems in an asp:DropDown - These Items are serialized INSTANTLY.

WHY CANT I FORCE THE DESIGNER TO SERIALIZE THE CONTENTS OF MY ITEMPLATE SO
THEY APPEAR IN THE MARKUP. Everybody else can but I can't? Why not?
 
N

Nathaniel Greene

This code below does everything, Except one caveat.
There is no way to force the <b> some default inner content</b> onto the aspx.
The user has to manually click in the editable region and hit enter or
spacebar.

Why can VS decide when to serialize the content to the .aspx page but not
the "designer" who is responsible for this?



public override String
GetEditableDesignerRegionContent(EditableDesignerRegion region)
{
IDesignerHost host =
(IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
if (host != null)
{
ITemplate contentTemplate;
if (CurrentRegion== 0)
{
contentTemplate = gActive.ContentTemplate;
String RetVal = ControlPersister.PersistTemplate(contentTemplate, host);
if (RetVal.Trim().Length==0)
{
String InnerValue = "<b> Some default inner content</b>";
region.Content = InnerValue;
// ((TemplateBuilder) contentTemplate).SetTagInnerText(InnerValue);
return InnerValue;
// ControlPersister.PersistTemplate(
// Tag.SetContent("hiiiiiiiiiiiiii");
// Tag.SetDirty(true);
}
return RetVal;
}
}
return String.Empty;
}
 
W

Walter Wang [MSFT]

Hi Nathaniel,

Sorry for delayed reply.

Get/SetEditableDesignerRegion will not get called if you don't have regions
in your control.

The built-in controls you mentioned uses collection and template properties
that are marked with [PersistenceMode(PersistenceMode.InnerProperty)]. If
you changes the value of one of those properties and calls
OnComponentChanged() from within your designer, this will cause the control
to get persisted again.

If still in doubt, please post more code of your control.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
N

Nathaniel Greene

Something like this? I've debugged it and verified that that method is being
called however it's not serializing anything.
}
public override
String GetEditableDesignerRegionContent (EditableDesignerRegion region)
{
IDesignerHost host1 =
(IDesignerHost)this.GetService(typeof(IDesignerHost));
String TmpC =
ControlPersister.PersistTemplate(this.gActive.ContentTemplate, host1);
if (TmpC.Trim().Length == 0)
{
TmpC = "<b>hi</b>";
ITemplate OldValue = gActive.ContentTemplate;
ITemplate NewValue = ControlParser.ParseTemplate(host1, TmpC);
TemplateDescriptor.SetValue(this.Component, NewValue);
// SetEditableDesignerRegionContent(region, );
RaiseComponentChanged(TemplateDescriptor, gActive.ContentTemplate,
NewValue);
UpdateDesignTimeHtml();
//ResetLayout();
// TmpC = "<b> Default fillter Cntent that omg</b>";
// SetEditableDesignerRegionContent(region, TmpC);
}
return TmpC;
}
 
W

Walter Wang [MSFT]

Hi Nathaniel,

To get the control to re-render, you just call UpdateDesignTimeHtml. To get
it to repersist (and also re-render), call OnComponentChanged(Component,
new ComponentChangedEventArgs(Component, null, null, null)).

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
W

Walter Wang [MSFT]

Hi Nathaniel,

Have you solved the issue? Would you please let me know the status of this
post? Thanks.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
N

Nathaniel Greene

That is still not doing anything. Are there certain events that it just can't
be called in?

I have verified that the below code is being called by placing breakpoints
inside the if statement. I've tried your method - I then found people
recommending using IComponentChangeService - but still no go. Am I doing
this in the wrong event and if so is there a better event to do it in?
public override
String GetEditableDesignerRegionContent (EditableDesignerRegion region)
{
IDesignerHost host1 =
(IDesignerHost)this.GetService(typeof(IDesignerHost));
String TmpC =
ControlPersister.PersistTemplate(this.gActive.ContentTemplate, host1);
if (TmpC.Trim().Length == 0)
{
TmpC = "<b>hi</b>";
ITemplate OldValue = gActive.ContentTemplate;
ITemplate NewValue = ControlParser.ParseTemplate(host1, TmpC);
TemplateDescriptor.SetValue(this.Component, NewValue);
IComponentChangeService c =
(IComponentChangeService)GetService(typeof(IComponentChangeService));
// this.Tag.SetContent("<ContentTemplate><b>hi</b></ContentTemplate>");
// UpdateDesignTimeHtml();
c.OnComponentChanged(Component, null, null, null);
// SetEditableDesignerRegionContent(region, );
// RaiseComponentChanged(TemplateDescriptor, gActive.ContentTemplate,
NewValue);

//ResetLayout();
// TmpC = "<b> Default fillter Cntent that omg</b>";
// SetEditableDesignerRegionContent(region, TmpC);
}
return TmpC;
}
 
W

Walter Wang [MSFT]

Hi Nathaniel,

Without full list of the objective, it seems we're having difficulty to
understand each other clearly. Is it possible for you to create a simpler
but complete control library, along with a short description of your
objective and current blocking issues. With such a project, we could
discuss more easily where to improve to achieve your objective; I can also
give more detailed and relevant suggestion on how to improve. Thanks.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
S

Steven Cheng[MSFT]

Hi Nathaniel,

Have you got any further progress on this issue? We're still closely
monitoring the thread and would be willing to continue help you on this. If
you still feel difficult and may need some further assistance from product
support team, I suggest you also consider contact CSS for help. Anyway,if
there is anything else we can help, please feel to post here.

http://msdn.microsoft.com/subscriptions/support/default.aspx

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 

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

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top