Pages

Tuesday, September 19, 2006

CS:Editor ViewState

Quick Tip:
CommunityServer 2.1 uses TinyMCE as a rich text editor. They use what appears to be a wrapper to TinyMCE: CommunityServer.Controls.Editor. As I am developing an application on top of CS 2.1 I am using the same rich text editor and encountered the following problem:
I was setting declaratively the Height Property of the Editor control, but it could not retain it's value after postbacks.
Look at the ASPX part:

So far so good but, after a postback the Editor control returned to its default height (messing-up my layout).

To make a long story short, it figured that something is wrong either with timing or with implementation. I mean that either the wrapper, or the wrapped control do not assign the value of Height before ViewState is saved, or they assign it to either a Property that is not saved in view state, or during an Event that fires before LoadViewState.

So what I did to work-around the issue was just disable ViewState in the Editor control.

The problem has gone away and that means that LoadViewState was overwriting my value.

I did not devote any time in looking further into this matter so I'm just posting this work-around, but if I do, I 'll let you know the details.

Monday, May 29, 2006

UseSubmitBehavior & GetPostBackEventReference

funny thing…

I needed a button (in an ASP.NET 2.0 page) to post-back and raise an event for another control. That means that I click a button but the post-back event is not handled by the button clicked but instead by another control on the same page.

The easy way was to add a System.Web.UI.WebControls.Hyperlink and set its NavigateUrl property to Page.ClientScript.GetPostBackClientHyperlink(myOtherControl, "Arguments")
But I wanted it to look like a Button so instead I added a System.Web.UI.HTMLControls.HTMLButton Control and did the same thing to its OnClientClick property.
All worked fine.

The funny thing happened when I decided that I like most to use a System.Web.UI.WebControls.Button instead.

ASP.NET Buttons are rendered as <input type="submit" /> controls. and by default their client-side onClick event is wired to the __doPostBack javascript method by ASP.NET.
To change that behavior in ASP.NET 2.0 we are supposed to use the UseSubmitBehavior Property which when set to false causes the Button to be rendered as <input type="button" /> and allows you to set the client-side onClick event programmatically (or declaratively) by setting the OnClientClick server-side Property.

That's what I did, only to discover that to whatever I was assigning to the OnClientClick Property, the original __doPostBack call was automatically appended by the framework.
I did not spend all the time in the world to figure this out and as I failed to find a reasonable way out of the problem, what I did, was to trick the client-side out of it by appending a JavaScript “return;” statement to the script I was assigning to OnClicntClick.

To make all these more obvious here is the hands on:
in the aspx/ascx file:


Notice that lines 5 and 6 above define the Hyperlink and HTMLButton that worked fine and line 7 defines the WebControls.Button that did not behave. Lines 1 to 3 define a DetailsView just because that is the control I wanted to handle the post-back event.

Now in the code file:

These get rendered as follows at run-time (if you look at the source in the browser):

This works just fine if you click on the Hyperlink1 or Button1 controls, but not at all if you clicked at Button2. That is because Button2 makes the call to __doPostBack twice. Once because I asked it to do so (by assigning its OnClientClick Property as you see in line 4 of the code-file above) and once because the framework automatically inserted the default post-back event reference for the button (Button2) itself.

To overcome this behavior (as I could not find another way around it) I just changed the last line in the code-file (line 4 in the snippet) by appending a javascript return statement as follows:

This caused Button2 to render as follows:

Notice the return statement (in bold) rendered between the two calls to __doPostBack. Although this does not prevent the second __doPostBack call from beeing inserted by the framework, it does prevent it from executing….

If you know a proper way out of this little puzzle  please let me know….

P.S:
  1. As you obviously noticed I needed the button to create an Insert button that would enable a DetailsView to go to Insert Mode even if the view has no items to display. The button (when clicked) causes the DetailsView to receive an Insert Command.
  2. Of course you fortunately do not need to do all this to make a details view to enter Insert Mode. It would be enough to just and any button with a server-side Click event handler changing the mode to Insert by just calling DetailsView1.ChangeMode(DetailsViewModes.Insert);

Wednesday, November 23, 2005

ASP.NET 2.0 Experiences


With this post I am opening a series -hopefully- of posts, based on my experiences with ASP.NET 2.0. This post by itself is at the moment incomplete.

I have been programming ASP.NET since version 1.0 and did most of my work in ASP.NET 1.1. Only recently, and just after the release of Visual Studio 2005 and the .Net Framework 2.0 I started working in ASP.NET 2.0. I have two initial goals to accomplish (apart from learning all the new and changed features of the new release):
  • I want to port my version 1.1 code libraries to ASP.NET 2.0
  • I want to create a web project I had in mind for the last couple of months in ASP.NET 2.0
In the future I will probably work in ASP.NET 2.0 exclusively and I also might want to port some of my version 1.1 apps to version 2.0.

My first findings so far:
  • ASP.NET 2.0 includes a framework for web site membership, role based security, and personalization. It is based on the same authentication and authorization mechanisms that come from version 1.1 but introduces the use of a data store and a "provider" API to support the new features. Previously I used to use my own implementation of such features using a custom solution. The new version makes my relevant code somewhat obsolete. I am already trying membership, roles and profiles and finding them easy and helpful. I 'll get back to you with more specifics on this...
...to be continued...

Friday, November 18, 2005

My Funny Surprises With .NET 2.0


As I was developing applications for .Net Framework 1.0 and 1.1, I was building a couple of code libraries with features I found smart and useful for my apps.

Being an active member of dotNetZone.gr, (a Greek .net developer community often nicknamed DNZ), I recently decided to share some of that code with others in DNZ.

The idea was to do that while porting the code to .Net Framework 2.0 through Visual Studio 2005.

Now, what’s so funny about that?

First thing I wanted to share was my Wizard classes. I implemented them in the context of a web project and used to find them brilliant.

Using SourceSafe Ι started today pinning and branching code to a new VS 2005 solution that would contain the part of my libraries related to Wizards.

“Come on! Where is the funny part?” you would still ask!

Well I compiled it and got the following compile time errors:
  • Error1: 'Wizard' is an ambiguous reference between 'System.Web.UI.WebControls.Wizard' and 'Softbone.Shared.Wizards.Wizard' 
  • Error 2: 'WizardStep' is an ambiguous reference between 'System.Web.UI.WebControls.WizardStep' and 'Softbone.Shared.Wizards.WizardStep' 
  • Error 3 'WizardStepCollection' is an ambiguous reference between 'System.Web.UI.WebControls.WizardStepCollection' and 'Softbone.Shared.Wizards.WizardStepCollection' 
(note: Softbone is "brand" name I am using, and Softbone.Shared is the namespace of the shared code library I am creating porting my code from .net framework 1.1 to 2.0).

Ooops!

Not only Microsoft implemented the same functionality as I did, but the just happened to have chosen the same class names as I did!

Well that, I thought was funny enough to mention…

So, it might be the case that my library is obsolete with the new version of the .Net Framework, but still, here is what is more interesting about it now than ever: I have to check my implementation against Microsoft’s one to see where mine falls short or even if I did some things that are better or smarter than Microsoft’s.

So I will be posting my code soon to my main blog and my .net blog in DNZ and keep you posted here, to see if I have more interesting or funny encounters during my Wizard Library porting to .Net Framework 2.0.

I ‘ll let you know….

Tuesday, August 23, 2005

GreekEuroVerbalizer

Reading a recent post in dotNetZone.gr I decided to implement as a proof-of-concept an algorithm using regular expressions to convert a decimal numeral representing an amount of money, to a verbal from in Greek text.

So to make it more obvious the problem was to convert 1,234,567.89 Euros to the string "One Million, Two Hundred Thirty Four, Five Hundred Sixtyseven Euros and Eightynine Cents" (only that the text should be in Greek and not English as I typed here to make the concept clear for everyone).

The algorithm I came up with is not the best that I could do but is enough as a proof of concept. Do not be alarmed if it seems too long at first glance. It's just the code comments that make it so long.

Here it goes:
You can also find this at the relevant blog article in dotNetZone.gr here (in Greek).

Saturday, August 6, 2005

MetaBlogAPI for CS 1.1


I wanted to test w.Bloggar and BlogJet today for posting in a CS 1.1 blog. MetaBlogAPI comes as a separate download from CS 1.1 so I tried to find and get it. Believe me I had a real hard time!

After an hour or so of googling around for it, a friend from dotnetzone.gr finally pointed me to it.

Here it is:
http://www.telligentsystems.com/Solutions/license.aspx?File=cs_1.1_metablog

If you need it, go get it…

The other versions found in various posts in communityserver.org/forums are usually older versions and will just give you a "Method not found: System.Collections.ArrayList COmmunityServer.Blogs.Components.Weblogs.GetWebLogs(CommunityServer.ComponentsUser,  Boolean, Boolean, Boolean). (EGetRecentError)" error message.

I wish they had a more standard place for it on the web than just a form post…

Friday, August 5, 2005

CS default language problems

I run into an issue today regarding Community Server 1.1 (CS 1.1).
I changed the default language in communityServer.config from en-US to el-GR, only to get a runtime error.

The change:

<Core defaultLanguage="el-GR">

The error:

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.

Source Error:
Line 49: message = FindControl("Message") as Literal;
Line 50: if(message != null)

Line 51: message.Text = string.Format(ResourceManager.GetString("DisplayUserWelcome_AlternateUserWelcome"), CSContext.Current.SiteSettings.SiteName);

Source File: C:\Documents and Settings\rousso\My Documents\Visual Studio Projects\CS\1.1\50615src\src\Controls\User\AnonymousUserControl.cs    Line: 51

Stack Trace:

[FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.] System.Text.StringBuilder.AppendFormat(IFormatProvider provider, String format, Object[] args) +1232

System.String.Format(IFormatProvider provider, String format, Object[] args) +65
System.String.Format(String format, Object arg0) +47
CommunityServer.Controls.AnonymousUserControl.AttachChildControls() 
CommunityServer.Controls.TemplatedWebControl.CreateChildControls() 
System.Web.UI.Control.EnsureChildControls() +100
...
System.Web.UI.Control.PreRenderRecursiveInternal() +125
System.Web.UI.Page.ProcessRequestMain() +1499


After meddling around a a little bit I pin pointed the problem to a translation error.

I turns out that the Greek language resource files located in /Languages/el-GR/Resources.xml were not properly (if at all) converted to reflect changes in code between version 1.0 and 1.1 of CS.

This line was the problem:
<resource name="DisplayUserWelcome_AlternateUserWelcome">Καλώς ορίσατε στο {0} {1}resource>

There, two String.Format arguments are obviously expected. On the other hand, line 51 of AnonymousUserControl.cs, only passes one (see source error above).

Removing the second placeholder from the format string solves the problem:
<resource name="DisplayUserWelcome_AlternateUserWelcome">Καλώς ορίσατε στο {0}resource>
The same stands for fr-FR (French) language resources I checked. Probably for others too.

If you can read Greek see my relevant posts in dotnetzone.gr. Also if you are looking to solve the same problem for the Greek (Hellenic) language see these posts in dotnetzone.gr where you can get the corrected translation for Greek text and buttons (it is attached to the post).