LavaBlast Software Blog

Help your franchise business get to the next level.
AddThis Feed Button

Skinned Login Control

clock April 14, 2008 14:16 by author EtienneT
Here is our login form in FranchiseBlast.  We think it's a pretty cool login form and it was not that hard to do.  It only requires basic CSS and some jQuery.
 
 

How we did it

The only things you need is an image like this one here:

inputLogin

Then we used the following CSS to define our text boxes style.  The "Login" css class is applied to the ASP.NET Login control and the class "TextBox" are applied to both textboxes in the login control.

.Login .Textbox, .Login .Hover
{
    width: 337px;
    height: 17px;
    background:transparent url(images/inputlogin.png) no-repeat top left;
    color: Black;
    border: none;
    padding: 5px;
    font-weight: bold;
}
  
.Login .Hover
{
    background:transparent url(images/inputlogin.png) no-repeat bottom left;
}

 

Has you can see, the only difference for .Hover class is that we tell the background to show the bottom of the picture (the orange part) instead of the top of the image.  If Internet Explorer supported the "focus" CSS pseudo class then it would be much simpler, but IE doesn't support it, so we have to use jQuery to achieve the effect.

Don't forget to add jQuery.js somewhere in the page and then you can add the following script to your page:

$('.Login .Textbox').focus(function(){
  $(this).attr('class', 'Hover');
});
  
$('.Login .Textbox').blur(function(){
  $(this).attr('class', 'Textbox');
});

 

Basically the code above registers an event to all DOM elements which have the "Textbox" CSS class and are children of a control of the "Login" CSS class. The first call registers an event handler on the focus event of the text box which changes the class to Hover.  We do the exact opposite for the blur event when we the text box loses it's focus.   There may be a better way to do this why jQuery; if you know how, let us know.

Finally, as a special added touch, we use an AnimationExtender after a successful login:

<ajax:AnimationExtender ID="animLogin" runat="server" TargetControlID="LoginButton">
<Animations>
    <OnClick>
        <Sequence>
            <FadeOut Duration=".5" Fps="20" AnimationTarget="pnlLogin" />
        </Sequence>
    </OnClick>
</Animations>
</ajax:AnimationExtender>

 

One last thing, if you use this AnimationExtender, you have to make sure your validators don't run on the client side. Validation must occur on the server otherwise the fade out animation will still occur and the login control will disappear. For example, we used a RequiredFieldValidator for both the username and password text boxes and we had to set the EnableClientScript property to false on both these validators.

This concludes how to do a skinned Login control à la LavaBlast.

kick it on DotNetKicks.com

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


10th Annual Québec Entrepreneurship Contest

clock April 10, 2008 14:05 by author EtienneT

contest As stated in one of our recent software start-up posts, we submitted our full-length business plan in this contest : 10th annual Québec Entrepreneurship Contest.  In the east part of Montreal alone, over eighty business plans were submitted.  Two weeks ago, we learned we were amongst the twenty-some finalists for the first round of the contest (there are three rounds: local, regional, national). On Monday, we had a short interview with the jury who decided which of the finalists would win in each category. It was a good way to practice our pitch, not only with the jury but also the other entrepreneurs that were being interviewed. Yesterday, at the awards ceremony for Montreal-East, we won the first prize in the Technological & Technical Innovation category.  Woohoo :). We won a cash prize and a one year membership to the chamber of commerce. 

We wanted to congratulate our good friends at Web Estate Management who also won a prize in the Services category! We had a long chat with the winners of the transformation / manufacturing category, Brik-a-Blok Inc.

Writing a business plan is a complex exercise if you want to do it properly. However, participating in a business plan contest can give you the small push you need to actually write it down and define your vision and your short/long term plan. If you aim to be a well-rounded software engineer doing more than coding, writing your plan brings a bit of variety to your day and allows you to distance yourself from the code for a few hours. We tackle business issues as if they were engineering problems and learned a lot during the whole process. (It is a known fact that it is the exercise of writing the plan that is valuable, not the document itself, which will evolve with the company.)

Even at this stage of the contest, we've already met some really interesting people that showed interest in our solution and had a few business propositions. The visibility that such a contest can offer in the media cannot be underestimated; some newspapers will most probably mention our company along with our sexy faces.

Yesterday was the ceremony for Montreal-East; we are now participating in the regional contest.  We'll know at the end of the month if we are in the finalists!  Wish us luck!  Regardless of the outcome, this was a very gratifying experience.

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Software Startup Lessons (Part 2): Communication and Collaboration

clock March 17, 2008 09:39 by author EtienneT

Welcome to part two of our three part series describing the various lessons we learned during our first year of a software startup.  You are encouraged to read the first part if you haven't already!

Problem Statement

In Part 1, we described our business' context and how we eat our own dog food. Indeed, we use the software we produce on a daily basis, helping us create quality products. A parallel can be made with our distributed team's communication patterns. Simply put, we're not all at the same central office, talking to each other all day. Our structure resembles that of a franchisor with franchisees distributed a several physical locations. The main reason we are distributed is to keep costs down while we develop our core infrastructure, but it does have the interest side-effect of forcing us to use the same communication tools a franchisor would.

Not only do we not work in the same building, we're not even in the same city! Because we work in independent offices, we have a greater control over our environment, which increases our productivity. Spolsky often talks about how developers should have private offices because outside disturbances kick us out of our zone. You can respond to your email every 15 minutes, but you can't make someone wait at your door for 15 minutes while you polish off a complicated algorithm.

In any case, given the fact that most geeks are not social creatures, you probably think that doing the majority of your interactions over the Internet is great, right? In reality, it's not always convenient  but we've started to become really creative (and efficient) with the tools we found to maximize our interactions.

We spend most our time chatting coordinating on Google Talk and move to Skype when voice conversations are required. Over time, we discovered some pretty nice software to communicate and we want to share these tools with you in this article.

Problems:

  • How do we talk to each other and with people outside our company?
  • How do we exchange files?
  • How do we manage our requirements?
  • How do we demo our software, how do we program in pairs?

Lesson 4) Talking to People

Carrier pigeons might have played a vital part in WWII communications, but we're using more modern techniques.

Skype

imageSkype is the obvious choice for voice communication over Internet.  Don't tell us that you haven't heard about this tool before!  Because we are four partners in LavaBlast, we often need to have conference calls. All our meetings are done online via Skype conference calls, at no cost to us. Furthermore, we can call up a client on their regular phone using SkypeOut.  SkypeOut will call the client's real phone and will connect them to our conversation, at very affordable rates. Indeed, for $3 a month, we obtained unlimited outgoing calls to Canada and the US. Setting up a conference call is really easy and the quality is good (most of the time).  You simply need a good microphones and you're good to go.  In addition, if you have a webcam and a good Internet connection, the video quality of Skype is just amazing especially compared to MSN.  Talking to someone who also has a good webcam and a good Internet connection is almost lag free, in my experience.

Having a central phone number for a distributed office

Since we have a distributed office, we need to have a central phone number.  The most affordable solution that we found was Skype for business.  Basically you simply need to register a SkypeIn number anywhere in the US (not available in Canada yet) and when people call this number, it calls you on Skype.   The cheapest way to get your incoming phone number is to purchase Skype Pro (at $3/month) and purchase the number for $38 a year (and it was operational within minutes of purchase!). You can forward calls to another user or normal phone and even get voicemail with Skype Pro. Optionally, you may install the business version of the Skype program for additional functionality. Therefore, all the incoming calls go to our main salesperson and, if more technical details are required, the call can be forwarded to us.  Skype for business has a nice business control panel to control Skype credit purchases, phone number assignments, and much more. Additionally, because the phone number is associated to the company, we can redirect it to a new person if an employee is replaced or if someone is on vacation. We could have a 1-800 number, but I don't think we have the kind of call volume that would justify having one just yet.

We found the perfect phone number for LavaBlast: 1-201-467-LAVA (5282).  SkypeIn personal has a nice interface to check if a number is available, but the business panel interface doesn't.  If you want to purchase a specific number, I wish you good luck because you have to generate the numbers one by one!  We wanted a number that ended either with BLAST or LAVA;  we found the number with the SkypeIn personal interface and then tried to regenerate it, one number at a time, in the business panel.  We finally found one that ended with LAVA but couldn't find one that ended with BLAST.  The best way we found to generate multiple numbers was to press Ctrl and click like crazy on the generate button to open new pages in new tabs.  We eventually found the number we wanted!

Lesson 5) Exchanging Files

There are lots of cool startups focusing on better ways to exchange files and we're keeping an eye on them. For now, here's what we're using.

Subversion

As software developers, we obviously use source control to manage our code. No surprise here. We even deploy our web applications using Subversion.

FranchiseBlast

image We've developed a document repository in our franchisee/franchisor collaboration solution. We post our user manuals and a few other documents on there; it is our distribution center for completed documents.

Microsoft Groove

We use Microsoft Groove which is a party of Office 2007, as our main internal document management tool. Groove is much more than a document repository, but we only use this feature.  Groove is simple to use and install because it distributes the files on all the peers instead of having to setup a complex server. Furthermore, it is better than a shared network drive because it has change notifications plus it can be accessed even when you are offline. There are a few drawbacks, but in general, it's a good simple solution for the low volume of Office documents we work on. 

Lesson 6) Requirements Engineering

The first post on the LavaBlast blog was related to requirements engineering and how we managed our pile of requirements written on the back of (sometimes used) paper napkins. More seriously, we've found it very beneficial to collaboratively define our software requirements with our clients. Constant feedback is the key to writing good requirements, and using collaboration tools is a must.

Wikis

We've been playing with ScrewTurn wiki as our main wiki over the last year, for both for our internal use and to interact with our clients during the requirements engineering process. It is very easy to install (trivial) and it is very very fast. Editing a page is very pleasant because it is nearly instantaneous when you save a page... it just feels blazingly fast. Furthermore, because it is a free and open source project, you get to spend money on Super Mario Galaxy instead.

During our software engineering capstone project, we used TWiki as our primary requirements engineering tool, a couple years before the strategy was discussed in IEEE Software. Although we've enjoyed ScrewTurn's simplicity during the last year, I think we're ready to revert back to the more feature-rich TWiki. Installation is a pain (less now than before), but the syntax much more natural. Furthermore, we already have the infrastructure in place (using page meta-data) to let us manage our requirements.

Lesson 7) Desktop Sharing

Today, sharing your desktop is an essential operation for any software startup. You can easily demonstrate applications to potential clients or perform pair programming, without having to be at the same physical location.

Lotus Sametime Unyte

Trying to explain something to someone over Skype is not always fun, especially when the client is not a technical person. Because a picture is worth a thousand words, showing software is much quicker!  During most of our first year, we used Unyte to do just that.  With Unyte, you simply have to start the application, decide which window to share (or share the entire desktop) and then send a link to the person (or group of people) that need to see it.  Recipients click on a hyperlink and load up a browser-based Java applet to see the shared windows. It's as simple as that.  The client doesn't have to install anything and it's fast! The host will receive an alert when the viewers can see his screen.  Unyte, used in conjunction with Skype, is really a great mix for meetings and sales demonstrations. We used the version for five people and it worked well, until we found Microsoft SharedView.

Microsoft SharedView

A few weeks back, we discovered Microsoft SharedView while it was still in beta. SharedView is similar to Unyte, but 15 people can participate in a shared session.  The only big drawback is that everyone has to download the software.  So if you want to quickly present something to a client, it's a little bit more complicated if they have to install it.  However, SharedView does allow any participant to share their desktop for the others to see (only one person can share at any given time). During a software demo, we used this capability to have the client show us their current point of sale! Additionally, the software gives other people the possibility to take control of the session and perform operations on the computer that is sharing an application. You can also share documents pretty easily with everyone and send chat messages, but we still use Skype for voice communication. We now prefer SharedView to Unyte when it is a possibility to install software on every participant's computer.

Lesson 8) Blogging!

We've been able to connect with tons of great people thanks to our blog, and have lots of fun perfecting our writing skills. We find that figuring out what to say (and what your audience is interested in hearing) is the hardest task when you start a blog. We still don't know if we should focus on giving away code or writing more experiences pieces like this one. Let us know!

BlogEngine.Net

Our blogging software, BlogEngine.Net, is simply terrific.  Free, fast, really easy to theme, has some good extensions and integrates really well with Windows Live Writer.  One of the main advantages for us is that it is open source and it is written in .NET, allowing us to perform minor behavior changes as needed.   It still has a few bugs that can be annoying, but from what we have seen so far, it is performing really well.  It supports multiple authors, an important feature for us because we have two people posting on the blog.

Lesson 9) When not to use communication tools

The most important lesson we learned during our first year of operations as a distributed development team wasn't a revelation but rather a confirmation of our expectations. Communication and collaboration tools are great, but technology doesn't solve conflicts. We're a closely knit team and have worked together for a number of years, greatly reducing the number of conflicts we may have. The conflicts we have are generally superficial, but as an example, let's consider an architectural decision where the two decision makers have divergent opinions on the best solution. Although instant messaging is great for efficiency reasons, it is not the best medium to argument on the merits of your solution. Indeed, we've all seen the politically incorrect "Arguing on the Internet is like running in the Special Olympics; even if you win, you're still retarded". The main problem is related to the lack of emotional expressiveness of concise instant messages or emails and since it is discussed in great lengths by very good authors, we'll leave a detailed analysis of the situation to them! As a side note, firing people via email might have seemed like a good idea for RadioShack, but we at LavaBlast shall stay away from such brilliant strategies!

Conclusion

Communication is the most important part of starting a business. Even if you're the only person in your company, you still have to communicate with your customers! We hope that you'll discover at least one cool collaboration tool today! Remember to come back next week for Part 3 of our series.

kick it on DotNetKicks.com  

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


RESX file Web Editor

clock February 7, 2008 08:35 by author EtienneT

Source CodeDEMO

If you have a multi-language site, you have probably already worked with .resx files.  Resx files are resource files that can contain strings, images, sounds... pretty much anything.  However, in ASP.NET (at least in our typical scenarios), resource files mainly contain strings to be translated in multiple languages.  Those needing a refresher course on ASP.NET localization should take a peek at this article: ASP.NET Localization. Let us take a typical ASP.NET application as an example.  When you generate a resource file for a file named Default.aspx, VS.NET generates a new folder named App_LocalResources (if it doesn't exist) and it creates a new file named Default.aspx.resx in this folder.

image

This option will only be visible in the design view of an aspx or ascx file.  

Default.aspx.resx will contain all strings that can be localized from Default.aspx.  Default.aspx.resx is the default resource file for Default.aspx.  It will contain the default language strings, in our case English.  Should you need to offer the same application in more than one language, you will need to create locale-specific resource files with a similar filename. For example, Default.aspx.fr-CA.resx would be a resource file for Canadian French. The logic to retrieve a string from the appropriate resource file is built into the .NET framework (it depends on the current thread's culture).

Those who have built a dynamic web site supporting multiple languages know that managing resx files is a burden, especially when the application changes.  TeddyMountain.com is a web site we recently created which provides English, French, and Danish versions.  We use a CMS for most of the text, but some dynamic pages like the store locator contains text which needs to be in resources files.  We collaborated with a resident of Denmark to translate the website; the translator is not a programmer and could not be trusted with the XML-based resx files. Furthermore, as the site is in constant evolution, we wanted a dynamic solution to avoid losing time exchanging Excel files.

Although there are some commercial applications out there, we decided to make a a simple tool to unify a set of resource files.  We wanted to take advantage of the fact that the we were building a website and we could have the translator use a web-based tool to translate the website. This has the advantage of being able to see the changes immediately in-context, instead of simply translating text locally. We made a class that would merge our Default.aspx.resx, Default.aspx.fr-CA.resx, and Default.aspx.da.resx files into a single C# object that is easy to use.  Once the data is in the C# object, the data can be modified and saved back to the disk later on.

We called this C# object ResXUnified.  The only constructor to ResXUnified needs a path to a resx file.  Then it will find all resx files related to it from different languages.  Once you have constructed the object, you can access the data simply by using an indexor:

ResXUnified res = new ResXUnified("Default.aspx.resx");
string val = res["da"]["textbox1.Text"];

In the above code, we access the Danish language file and query the value of the "textbox1.Text" key.  This information can be changed and saved back to the disk:

res[""]["textbox1.Text"] = "Home"; // Default language we can pass an empty string
res["da"]["textbox1.Text"] = "Hjem"; // Danish
res["fr-CA"]["textbox1.Text"] = "Acceuil"; // French
res.Save();

When we call Save(), only the files that were changed will be written to the disk.  ResXUnified simply uses a Dictionary and a List to manage the keys and the languages.  To save, it uses the ResXResourceWriter class provided by the framework, which makes it easy to manipulate resx files. Similarly, we read resx files using the ResXResourceReader class.  Without these two classes, manipulating resx files would be much more complicated.

I won't include more code here since this is a pretty straightforward collection class.

Later, for the TeddyMountain.com website, we made a quick interface in ASP.NET (see the demo here) to display all the resx files in a project. We enable the user to add a language file and translate all the fields from the default language.  Here is an example:

image 

When a string needs to be translated, the textbox background color is not the same, this way it's easy for the translator to see what needs to be translated.

The generate local resource button in Visual Studio generates a lot of "useless" strings in resx files; we don't necessarily want to enter tooltips on every Label in our application. To make it easier to read, we designed an option to hide or show these empty strings.

This tool is pretty basic right now and there are more options that could be easily added.  For example, we could add a list of files that remain to be translated or allow for multiline strings (notice we don't support line-breaks in our strings). We encourage you to modify the code and show off your enhancements!

Final notes: If you try the code out, please remember to give write access to the ASP.NET worker process in all the App_LocalResources folders (and the App_GlobalResources folder if you use it). Also, since changing resx files for the default language restarts the web application, it is recommended you use the tool on a development copy of your website.  

Source CodeDEMO

kick it on DotNetKicks.com

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


ViewState property code snippet

clock January 23, 2008 12:47 by author EtienneT

One of the things I do frequently is making a new viewstate property to use in a UserControl in ASP.NET.  (Yes, we know, ViewState is evil. We store it in the session and use it in low-volume sites.) Just download this code snippet, open Visual Studio, open Tools->Code Snippets Manager, and finally Import.

ViewState Property.snippet (1.28 kb)

You can then use it just by writing the shortcut in the code editor and pressing TAB.

image

Here is the result:

image

Using the ?? operator is nice since we don't have to do ugly ifs to return a default value and we don't have to assign something in the ViewState either.  We just fill the ViewState when we need it. This avoids bloating up the ViewState with default values.

ViewState Property.snippet (1.28 kb)

kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


CheckBoxList hover extender

clock January 22, 2008 09:16 by author EtienneT

Summary

This article presents a CheckBoxList extender that enables the user to hover over individual checkboxes in the list and see a popup with additional information.  The information is populated dynamically (web service call) depending on the hovered checkbox' value.

[VIEW THE ONLINE DEMO]

[DOWNLOAD THE CODE] (469.00 kb)

Where could this be useful?

If you use the ManyToManyList in SubSonic, you know that it inherits from the built-in CheckBoxList control to display data from a many-to-many database relationship.  You probably also know that this can be really useful, but it has it's limitations.  We are using the SubSonic many-to-many list to display a list of stores that a user can be associated with.  You can display only one field of information by item with the ManyToManyList control for the foreign table associated in the relationship (unless you use views!).  Here is an example:

storesList

For a particular user, we are listing all possible stores and showing the store ID as a description for the items.  This can have a meaning for some users, but when a new user comes in and doesn't know the store identifiers, you have a problem. All franchise stores share the same store name as they do business under the same name - they can be uniquely identified by their franchisor-assigned ID or by their address. However, we don't want to show too much information in this control, as it would clutter the interface, in our system. We need a way to display more information by item, without taking up too much screen real estate.  

Our solution is very much inspired by the AjaxControlToolkit controls, such as the HoverMenu to display information when the user hovers over an item in our CheckBoxList (or SubSonic ManyToManyList).  We created an AJAX Control Toolkit Extender that asynchronously calls a web service method (or a page method) to obtain the information displayed in the popup control, when the user hovers over an item.  Here is an example of the result:

checkboxListhover

How to use it

You need a CheckBoxList, a panel to display the information, our extender, and a web service method to invoke.

<asp:CheckBoxList ID="CheckBoxList" runat="server">
    <asp:ListItem Text="Item #1" Value="1" />
    <asp:ListItem Text="Item #2" Value="2" />
    <asp:ListItem Text="Item #3" Value="3" />
    <asp:ListItem Text="Item #4" Value="4" />
    <asp:ListItem Text="Item #5" Value="5" />
</asp:CheckBoxList>

<asp:Panel ID="panelInfo" runat="server" CssClass="checkboxlisthover">
    <asp:Label ID="lblTest" runat="server" Text="Label"></asp:Label>
</asp:Panel>

<ajax:CheckboxListHoverExtender
id="checkboxlistext" runat="server"
TargetControlID="CheckBoxList"
PanelID="panelInfo"
DynamicServiceMethod="GetContent"
DynamicControlID="lblTest"
DynamicServicePath="~/CheckBoxList.asmx" />

The web service class should look something like this:

[ScriptService]
    public class CheckboxList : WebService
    {
        [WebMethod]
        [ScriptMethod]
        public string GetContent(string contextKey) { return "";}

    }

Implementation

A web service method was called with the value of the hovered checkbox.  When you DataBind the CheckBoxList, it is very important to assign a value to each of your ListItems.  In this example, each checkbox has a GUID value.  This GUID is passed as a parameter to the web service call automatically by the extender.  The popup panel is then filled with the information returned by the web service.

As stated previously, the CheckBoxListExtender control is very much inspired by the HoverMenu extender.  The two controls have similarities, but we can't use the HoverMenu directly in the CheckBoxList because we don't have access to the item template of a CheckBoxList.  This prevents us from using the built-in HoverMenu extender for each CheckBoxList item.

Coding a new extender

To code a new extender, you can use existing extenders to simplify your life: that's what we did for the CheckBoxListExtender.  It re-uses the HoverExtender and the PopupExtender.  Those two extenders are not in the sample page of the AjaxControlToolkit (we see the HoverMenuExtender and PopupControlExtender but not the two we are using here), but they are in the source code if you want to see them.  Basically when we coded the CheckBoxListExtender, we had to pass the scripts we wanted to depend on:

[RequiredScript(typeof(CommonToolkitScripts))]
[RequiredScript(typeof(HoverExtender))]
[RequiredScript(typeof(PopupExtender))]
[RequiredScript(typeof(AnimationExtender))]

[Designer(typeof(CheckboxListHoverDesigner))]
[ClientScriptResource("LavaBlast.AJAX.CheckboxListExtender.CheckboxListHoverBehavior", "LavaBlast.AJAX.CheckboxListExtender.CheckboxListHoverBehavior.js")]
[TargetControlType(typeof(CheckBoxList))]
public class CheckboxListHoverExtender : DynamicPopulateExtenderControlBase

As you can see, the extender inherits from DynamicPopulateExtenderControlBase.  This means that the extender can dynamically populate the control via a web service call and all the necessary plumbing is already in place. Specifying the scripts you depend on is as easy as using the RequiredScript attribute on your extender class.

JavaScript behavior

As for the JavaScript, for each "TD" inside our CheckBoxList control, we created a HoverBehavior (this is from the HoverExtender).  Each time the HoverBehavior events are fired, we can do something about them.  In this case, we simply activated the PopupBehavior to show the popup panel and call the web service method to populate the content.  As the value of each checkbox of the list is not contained in the DOM of the page, most probably a security feature of ASP.NET, you have to somehow pass this information from the server to the extender behavior.  Since we couldn't find a way to pass a list of values from the server to the behaviour using a generic List variable, we simply used a string of comma separated values.  Right now we're using this:

[ExtenderControlProperty]
[DefaultValue("")]
[Browsable(false)]
public string Values
{
    get { return GetPropertyValue("Values", ""); }
    set { SetPropertyValue("Values", value); }
}

But would much rather like to use the following: 

[ExtenderControlProperty]
[DefaultValue("")]
[Browsable(false)]
public List<string> Values
{
    get { return GetPropertyValue("Values", ""); }
    set { SetPropertyValue("Values", value); }
}

It appears generic lists are not supported, unless we are mistaken. If someone knows if this is possible, please leave us a comment on this post.

Don't forget to look at the online demo!

CheckBoxListHoverExtenderDemo.zip (469.00 kb)

kick it on DotNetKicks.com

Currently rated 3.0 by 2 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Using { and } in string.Format

clock January 16, 2008 14:02 by author EtienneT

Have you ever tried to use the { and } characters in the c# string.Format() method?  If you have, then you probably ran into a problem.  I'm posting this because this little Gotcha might not turn up until much later if your string formats are dynamically loaded from some external source, such as RESX files.

In any case, I sometimes find it useful to write some JavaScript code directly in C# and then dynamically insert it into the page with the ScriptManager.  Here is a quick example:



Basically, I write my JavaScript code on multiple lines with the @"" notation.  Then, I have to escape all { and } characters using {{ or }} otherwise string.Format will run into a System.FormatException: Input string was not in a correct format exception.  I can customize my JavaScript (or insert control.ClientID parameters) this way while retaining a readable format in the C# code.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Search

Calendar

<<  July 2008  >>
SuMoTuWeThFrSa
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

Archive

Tags

Categories


Blogroll

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Sign in