First video to Silverlight 3 appeared on Channel 9

March 11th, 2009

On Channel 9 Brad Adams and Robert Hess are talking about the third Version of Silverlight. In more detail they are talking about "Silverlight 3.0 for Great Business Apps".

So as the title let’s except, there are features in the next Silverlight version that make it easier to build business applications. There are different things mentioned in the video, but "the super secret stuff" will be told at MIX09 in Las Vegas next week (starting at the 18th of March). So the most interessting points from the video are:

  • New set of controls ("tons of new controls")
  • Support for Back/Forward-Buttons of the Browser
  • Validation support

There is nothing said about commands (even if some logic for commands can be used from Prism2), nothing about Triggers, nothing about CollectionViews etc. All these points would be great for Business Applications that target the Model-View-ViewModel-Pattern.

So let’s wait what the MIX09-conference will bring. Today there is neither a Beta nor a Customer-Technology-Preview of Silverlight 3, but community voices expect a Beta or CTP to be released after MIX09 this month. I’m looking forward to grab it.

Just converted my PHP / CSS-based Homepage to a Silverlight 2.0 Website

March 2nd, 2009

Three weeks ago on a saturday morning I spent my thoughts on what to do with this last free saturday before the football-season starts. Unfortunately my girlfriend was not here, so Tabletennis was no alternative. But there were other possibilities:

  • Play Guitar all day long
  • Play on my new Tenorhorn (I haven’t told you that, right?)
  • Put my snowboard under my feet and go up on the mountain
  • Do some muscle-training and try to push up the 105kg more than 12 times
  • Look that Bankjob-DVD

… while I was thinking about all that, I surved on www.silverlight.net and then I thought, why not just build my classic homepage (http://www.thomasclaudiushuber.com) totally with silverlight 2.0. And that’s what I’ve done on that morning. :) Yesterday I’ve finished the page by implementing a php-call from Silverlight to make the contact-formular work (I’ve no ASP.Net-Support on my Webserver) Take a look at the resulting Silverlight-page on http://www.thomasclaudiushuber.com/pageInSilverlight.

I wanted the result to be as close as possible to the original page, and I think it is. Just with some animations. :-)

It was a rapid development process, but keep in mind that it’s also a really simple site. The language switch the php/css site has I left off in the Silverlight-Version, because I went also snowboarding in the afternoon as the snow-height is 63cm on the Belchen, a mountain in the black forest not far away from my home. Instead of the language-switch I’ve created a "fullscreen"-button (It was a one-liner :-)). I also didn’t make a real Dataaccess through WebService-calls. The text-parts are statically inside the XAML-documents. But that wouldn’t be a big thing to change.

Through the development process of the Silverlight-page there were different things I knew from WPF and I was missing really extremly in Silverlight. Other things didn’t work as good as I thought they should. And at least there were also some good things. Let’s take a look at those that are "not so good":

The First "not-so-good": The TextBlock-Element can contain Inline-Elements. In WPF, there are many such Inline-Elements to format the text inside, like Bold, Italic, Run, LineBreak, Hyperlink, Span and so on. In Silverlight there are only two, LineBreak and Run. The one you will be missing most in Silverlight, as you are developing web-applications, is the Hyperlink-Inline. In WPF it allows you to create a hyperlink anywhere in the Text. As Silverlight doesn’t have this one, you can’t create a hyperlink inside your text out of the box. Silverlight has a HyperlinkButton, but that can’t be put inside a TextBlock. So what’s the solution? I’ve used a WrapPanel in combination with multiple TextBlocks and Hyperlinks so that it looks like the Hyperlinks are inside the Text. But in fact they aren’t, it just looks so. There are also ThirdParty-Controls available allowing you to write text that contains hyperlinks. I hope the Hyperlink-Inline will be available in Silverlight 3.0

The Second "not-so-good": The TextBlock-Element can’t justify the text it contains.

The Third "not-so-good": The Image-Element only supports jpeg and png-files. As the images in the "articles"-Section of my homepage were gif-files, I needed to convert them. Maybe in a future release of Silverlight the Image-Element supports more types. But this point isn’t really bad, it’s not a big thing to convert images.

The Fourth "not-so-good": If you set the silverlight plugin’s params windowsless to true and background to transparent, you can display a custom html-background. I tried that and set the silverlight-plugin to a width of 800. If you use such a html-background, your silverlight-content will flicker when you animate it. That’s because the plugin is in an overlay over the website. That wouldn’t change in future versions. So the golden rule is not to use animations if the plugin’s background is transparent and the plugin is windowless. Or another option is to set the plugins width and height to 100% so that you don’t see any other html-contents. The latter I’ve done.

The last "not-so-good": The Enum-class has no GetNames-Method. To loop through an enum, you’ll need reflection. I’ve done it this way, where Category is my enum:

foreach (FieldInfo fi in typeof(Category).GetFields(
  BindingFlags.Static | BindingFlags.Public))
{
  Category category =
    (Category)Enum.Parse(typeof(Category), fi.Name, true);
  …
}

Ok, that’s all. There are also more points, e.g. Silverlight doesn’t support Triggers and Commands out of the box. But I’ll only mention those points that have been important when converting my website to Silverlight 2.

Now let’s take a look at the great things. I’ll just mention three:

The First "great one": You can use C# and common .NET classes you are already familar with. This aspect is really a big one, even if it was said already so much.

The Second "great one": With Expression Blend and Visual Studio, Animations and UI-Design can be done very fast. If you’ve some experience with WPF-Userinterfaces, you’ll do it in Silverlight the same way.

The Last "great one": As my Homepage contains a contact-formular, I needed some service to call to send an email from that formular in Silverlight. Unforetunately my webserver doesn’t understand .asmx or .svc. So I tried to call a php-script from Silverlight for sending the email. And hey, it wasn’t difficult at all. The WebClient-class in Silverlight has everything you need to make a call on a lower level to anything in the web.

So stay tuned and take a look at the Site on http://www.thomasclaudiushuber.com/pageInSilverlight

WPF "Advanced Layout"-Session at BASTA

February 21st, 2009

Next week you can meet me at the BASTA - a German Conference about .NET, Visual Studio & more. I’ll give a presentation about Layout-functionality in WPF on Tuesday at 13.30 o’clock. After the presentation you can meet me (on Tuesday only) and other "Trivadians" (the whole week) at the "Trivadis"-stand.

I’m looking forward to see you there. :-)

Use the Network Services Shell to unblock WLANs in Windows Vista

February 10th, 2009

Yesterday I wasn’t able to connect to my own WLAN. The day before yesterday I was able, but yesterday I got the message that my network administrator has blocked me from connecting to this network. "Your network administrator has blocked you from connecting to this network".

blockedWLAN

The ironic thing is that I am the network administrator of this network. :-) As I hadn’t installed anything new on my machine, I wondered why my computer wasn’t able to connect anymore. Then I remembered that I got a bluescreen due to my swisscom unlimited card. My computer awaked from sleep and didn’t recognize the swisscom unlimited card anymore. I plugged-in the card again, and then I got a bluescreen. Unfortunately at this moment I was not in my home-wlan, so I didn’t recognize that it didn’t work anymore.

So the question was how to unblock this WLAN. I didn’t find any contextmenu or a Dialog to unblock it. So first I have deinstalled the software of the unlimited card. But that wasn’t a helpful idea. My WLAN was still blocked. (Normally the software of the unlimited card (called unlimited data manager) can manage your WLANs, then you’ll see them as blocked. But I didn’t tell the software to manage my WLANs, so I thought deinstalling would help, but it didn’t).

After deinstalling the unlimited card software didn’t help, I thought there’s only a way like a real admin would do - by a commandline-tool that gives you a little bit of linux-feeling.

Windows Vista contains a commandline-tool called "netsh" - the Network Services Shell. That tool was also shipped with XP and other Windows Operating Systems. Run that tool from the commandline with "netsh wlan" and you’ll see the available commands for WLANs. I looked at http://technet.microsoft.com/en-us/library/cc755301.aspx, where you’ll find all informations about administration of WLANs by netsh. There you’ll also find the "delete filter" command, that was the solution to my problem.

I’ve deleted the filters of denied infrastructure and adhoc networks by calling the following two commands in a cmd-Window with path to system32

>netsh wlan delete filter permission=denyall networktype=infrastructure
>netsh wlan delete filter permission=denyall networktype=adhoc

Both times I got the message "This filter is removed from the system successfully". Here’s the Console that shows what I’ve done.

netshDeleteFilter

After that step in the Console, my WLAN wasn’t blocked anymore and I was able to connect again… puhh, however, I’m still still wondering that there isn’t a GUI to unblock WLANs, even on a system called "Windows". ;-)

How-to deploy the Crystal Reports Basic Runtime that’s included in Visual Studio 2008

February 2nd, 2009

This week I’ve to deploy an ASP.NET application containing about 20 reports that have been created with the Crystal Reports Basic Runtime which is included in Visual Studio 2008. (By the way, the application also contains a lot of AJAX-Functionality. It uses the "AJAX Control Toolkit-based" MultiColumnDropDown that I’ve described in a previous post).

When deploying the application to a different machine than your developer-machine, the Crystal Report Basic Runtime must be deployed also. You do that by copying the necessary msi-file to the server and run it. The "necessary" .msi-file is already on your development machine and were installed with Visual Studio 2008. The .msi-files for different plattforms are located in the following paths:

Runtime | MSI-Location
(x86) C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\CrystalReports10_5\CRRedist2008_x86.msi
(x64) C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\CrystalReports10_5\CRRedist2008_x64.msi
(IA64)

C:\Program Files\Microsoft Visual Studio 9.0\Crystal Reports\CRRedist\IA64\CRRedist2008_ia64.msi

(the table above is contained in MSDN-documentation here)

The installation is very simple. You doesn’t need to click anything, simply run the .msi and you see the window below. Just wait until it closes.

crystalReportsBasic

There’s also the possibility to include the msi in your setup-application. For more information on that take a look at this thread in MSDN-Forums.

The PrintForm-Component in the Visual Basic Powerpack for Windows Forms

January 23rd, 2009

Did you ever wanted to print a Form without calling any native code? Well, with Windows Forms and Visual Studio 2008 this is a really simple exercise. When you design your WinForms-Application you’ll find a Tab Visual Basic PowerPacks in the Toolbox of Visual Studio 2008. In this Tab, you’ll find a component called PrintForm. Simply drop this component on your form, and you’ll find all the functionality you need. Let’s take a look at a small sample by using a very simple Windows Forms application.

The application just has a Browse-Button to browse an image from the filesystem, a PictureBox to display the image and a TextBox displaying the path to the image.

printForm_pic1

The Browse-Button does nothing more than showing an OpenFileDialog and setting the Text-Property of the TextBox to the selected file and assigning the chosen image to the Image-Property of the PictureBox.

private void btnBrowse_Click(object sender, EventArgs e)
{
  var dlg = new OpenFileDialog
    {
      Multiselect = false,
      Filter = "JPEG (*.jpg)|*.jpg|JPEG (*.jpeg)|*.jpeg"
               + "|GIF(*.gif)|*.gif|Bitmap (*.bmp)|*.bmp"
    };
  if(dlg.ShowDialog() == DialogResult.OK)
  {
    txtImagePath.Text = dlg.FileName;
    pictureBox1.Image = Image.FromFile(dlg.FileName);
  }
}

The Form above already contains a "Print Form!"-Button. The eventhandler of that Button is currently empty. Let’s implement it. But before that, go to the designer and drag’n'drop a PrintForm-component out of the Toolbox on the Form.

printForm_pic2

After dropping the PrintForm-component, you’ll find it in the Component Tray of the Windows Forms-Designer. It’s named printForm1 by default. I won’t change that here. Now let’s step to the EventHandler of the "Print Form!"-Button.

To print the form, first a PrintDialog is shown allowing the user to select a printer. Then the settings of the PrintDialog are assigned to the PrinterSettings-Property of the printForm1-component. The Print-Method on that component is called passing in the Form (this) and an Enum-Value specifying to print the full Window.

private void btnPrintForm_Click(object sender, EventArgs e)
{
  var dlg = new PrintDialog();
  if(dlg.ShowDialog()==DialogResult.OK)
  {
    printForm1.PrinterSettings = dlg.PrinterSettings;
    printForm1.Print(this, PrintForm.PrintOption.FullWindow);
  }
}

That’s all! :-) E.g. when I print into my PDFPrinter, the resulting PDF-Document will look like this:

printForm_pic3

Beside the PrinterSettings-Property the PrintForm-Component contains some more important properties . The most mentionable one is the PrintAction-Property. It’s of type PrintAction, an enum in Namespace System.Drawing.Printing. The PrintAction-enum contains three values, PrintToPrinter (the default for the PrintForm’s PrintAction-Property), PrintToFile and PrintToPreview.

So to show a preview of the Print-output, you simply need the following to lines:

printForm1.PrintAction = PrintAction.PrintToPreview;
printForm1.Print(this, PrintForm.PrintOption.FullWindow);

Replace the code in btnPrintForm_Click with the two lines above, and you’ll automatically get a preview, like shown below. But be careful. The user can print out of the Preview. If you’ve no PrinterSettings assigned to the PrinterSettings-Property of the PrintForm, the Print will be implicitly written to the users default-Printer.

printForm_pic4

So, that’s all. Get the sample here.

VisualStateManager in Silverlight

January 22nd, 2009

Last year I’ve written a german article for the dotnet-magazine about VisualStateManager in Silverlight. As this feature will also be part of WPF 4.0, take a look at the article, which is now available on my homepage. The article is also available on the homepage of Trivadis beside many other articles focused on other IT-Topics.

So read and enjoy. :-)

The promised code example with the ASP.NET Ajax Multicolumn-Dropdown

January 19th, 2009

During the last months I was asked many times for the code of the Multcolumn-Dropdown that I’ve described in this post. I’ve just created a very small sample-application containing such a dropdown. You can download it here.

If someone of you creates a control out of that source, I would be glad to get a link to it. :-)

Thomas

The Lottery-Console-Application used at the last WPF-Event @ Microsoft Usergroup Switzerland

August 25th, 2008

Last week we had a great WPF-afterwork-event at Microsoft Usergroup Switzerland (MSUGS) sponsored by Trivadis. I gave a deep-dive session about developing custom controls using WPF with many of it’s features like Dependency Properties, Commands, Routed Events, PART-Elements, Theme-Styles and so on.

At the end of the session a copy of my German WPF-book was drawn. We made a small lottery, but not a normal one. As all attendees were .NET-developers, everyone trusted in .NETs Random-class, so why don’t do it just in code?! We’ve written life a small console-application that did the job for us. As some people asked for the code (of course only the loosers and not the winner of the book ;-) ), here it is:

static void Main(string[] args)
{
  Console.WriteLine();
  Console.WriteLine("  — MSUGS- WPF-Book Lottery");
  Console.WriteLine("  Enter names and a dot (\".\")"
                  + " when names are complete");
  Console.WriteLine();

  List<string> names = new List<string>();
  Console.Write(">");
  string name = Console.ReadLine().Trim();

  while (!name.Equals("."))
  {
    names.Add(name);
    Console.Write(">");
    name = Console.ReadLine().Trim();
  }

  Random random = new Random();
  int winnerIndex = random.Next(names.Count);

  string winner = names[winnerIndex];

  Console.WriteLine();
  Console.WriteLine("Starting lottery…");

  Thread.Sleep(3000);

  Console.Write("And the winner is");

  for (int i = 0; i < 10; i++)
  {
    Thread.Sleep(1000);
    Console.Write(".");
  }
  Console.WriteLine();
  Console.WriteLine();

  Console.WriteLine(winner);

  Console.ReadLine();
}

The Console-Application looks like this:

image

The lucky winner at the MSUGS-event was Stefan, he was at index zero in the names-Collection. Congratulations!

st_msugs_080820

Thanks to MSUGS for the great organization and to all developers who attended in the session. I hope you enjoyed it.

Developing Multicolumn-DropDown/DropDownList with ASP.NET, the GridView and the AJAX Control Toolkit

July 31st, 2008

During the last months I was developing an ASP.NET application and I needed a dropdownlist to display multiple columns in each item. Everyone with a little knowledge in Web-development knows, that HTML doesn’t contain built-in support for multicolumn-DropDowns. HTML only knows a <select>-Tag that can contain multiple <option>-Tags, but each <option>-Tag just represents one column in the dropdown.

In this post we’ll take a look at different possiblities to display the properties of a simple Friend-class in one dropdown-"option". The Friend-Class looks like this:

public class Friend
{
  public Guid ID { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public DateTime BirthDay { get; set; }
}

Below you see the four approaches we’ll look at in this post:

  • The easieast way to do it: Using string concatenation
  • Use third-party controls that have the multicolumn-feature
  • Develop your one multicolumn-DropDown with AJAX Control Extenders
  • Make the multicolumn-DropDown usable for many rows

The easiest way to do it: Using string concatenation

The easiest way I can think of is to use simple string concatenation and a monospace font like courier new. First thing to do is to add an asp:DropDownList to your page. Don’t forget to set it to a monospace font. You can do this via style-Attribute.

<asp:DropDownList ID="friendDropDownList" runat="server"
style="font-family: ‘Courier New’, Courier, monospace" />

The DropDownList can be filled up in code-behind, e.g. in the Page_Load-Event. The most tricky part is to add multiple blanks. The DropDownList automatically encodes the added string to HTML and all blanks per default become one blank. That would cause the columns not to be displayed exactly below each other. One solution to this is to add blanks as a unicode escape sequence (\u00A0). The DropDownList will automatically convert these into "&#160"which can be interpreted by the browser.

protected void Page_Load(object sender, EventArgs e)
{
  PseudoFriendDataAccess da = new PseudoFriendDataAccess();
  List<Friend> friendList = da.LoadAllFriends();

  foreach (Friend f in friendList)
  {
    string text = string.Format("{0}|{1}|{2}",
      f.FirstName.PadRight(10,‘\u00A0′),
      f.LastName.PadRight(10,‘\u00A0′),
      f.BirthDay.HasValue?
      f.BirthDay.Value.ToString("dd.MM.yyyy"):
      "".PadRight(10,‘\u00A0′));
    friendDropDownList.Items.Add(
      new ListItem(text,f.ID.ToString()));
  }
}

The result for the DropDownList above feels like this:

I’ve to add that this solution via string concatenation doesn’t look really cool. So let’s take a look at other approaches.

Use third-party controls that have the multicolumn-feature

There are different third-party controls that have the multicolumn-feature. E.g. Infragistics has a WebCombo-Control that can display multiple-Columns. On Codeproject there’s also a Control availabe, but unfortunately with no source-code of the control itself: http://www.codeproject.com/KB/custom-controls/multiColsDD_List.aspx. I looked at this control, but I think it isn’t a great idea to use it for a professional application without having support and without having full source code.

So I’ve tried the Infragistics WebCombo. It worked very well up to 20 records when displaying about 5 columns. With 200 records it became very very slow in IE7. E.g. while the mouse cursor moved from item 90 to item 100, the WebCombo still showed the mouseOver-Color on item 90, then the mouseOver-Color moved slowly to item 91, 92, 93… The time used for this task was over 1 second till the mouseOver-color reached item 100. As I needed a multiple column dropdownlist with at least 200 items, the Infragistics WebCombo was no solution for me (I’ve used NetAdvantage_ASPNET_2008 Vol. 2_CLR2.x). Maybe the team of Infragistics can check this and make it faster for IE7.

So after evaluation more dropdowns from other vendors and after a phone call with Jean-Claude Trachsel, another ASP.NET-Professional@Trivadis, I decided to create a multiplecolumn-dropdownlist on my own using the AJAX Control Extenders and the build-in GridView.

Develop your one multicolumn-DropDown with AJAX Control Extenders and ASP’s GridView

Starting the development of a multicolumn-dropdown, the first thing to is is to add an UpdatePanel to your site:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
  <ContentTemplate>
    <!– all other content goes here –>
  </ContentTemplate>
</asp:UpdatePanel>

Inside the <ContentTemplate>-Tag of the UpdatePanel I place a TextBox and an ASP-Panel. The Panel’s Style is set, so that it isn’t visible per default. Below the Panel I’ve placed a DropDownExtender from the AJAX Control ToolKit. Download the Toolkit here. The DropDownExtender has a DropDownControlID- and a TargetControlID-Property. When the TargetControl is clicked (here the txtFriend-TextBox) the DropDownControl (here the FriendDropDown-Panel) becomes visible.

<asp:TextBox ID="txtFriend" runat="server"
  Width="100px" ReadOnly="true" />
<asp:Panel runat="server" ID="FriendDropDown"
  Style="display: none; visibility: hidden;">
  <!– GridView  goes here –>
</asp:Panel>
<cc1:DropDownExtender ID="DropDownExtender1" runat="server"
  DropDownControlID="FriendDropDown"
  TargetControlID="txtFriend">

As I’ve added the DropDownExtender out of Visual Studio’s ToolBox, the following Register-Directive was created automatically on my page and also an assembly-reference was set automatically.

<%@ Register Assembly="AjaxControlToolkit"
Namespace="AjaxControlToolkit" TagPrefix="cc1" %>

Next you’ve to add a GridView inside the FriendDropDown-Panel. Just drag it out of the toolbox and set the properties you need. Here the GridView is named FriendGridView. Two Eventhandlers are defined for the events RowDataBound and SelectedIndexChanged, which are necessary for this multicolumn-scenario. But before we look at the Eventhandlers in the Codebehind-file, first look at the invisibleColumn stye, which is set on the first BoundField in the GridView.

<asp:GridView ID="FriendGridView" runat="server"
  AutoGenerateColumns="false"
  OnRowDataBound="FriendGridView_RowDataBound"
OnSelectedIndexChanged="FriendGridView_SelectedIndexChanged">
  <RowStyle BackColor="#DDDDDD" />
  <Columns>
    <asp:BoundField DataField="ID"
      HeaderStyle-CssClass="invisibleColumn"
      ItemStyle-CssClass="invisibleColumn" />
    <asp:BoundField DataField="FirstName"
                    HeaderText="Firstname" />
    <asp:BoundField DataField="LastName"
                    HeaderText="Lastname" />
    <asp:BoundField DataField="Birthday"
                    HeaderText="Birthday"
                    DataFormatString="{0:dd.MM.yyyy}" />
  </Columns>
  <HeaderStyle BackColor="Blue" ForeColor="White" />
  <AlternatingRowStyle BackColor="#EEEEEE" />
  <SelectedRowStyle BackColor="#999999" />
</asp:GridView>

The FriendGridView has four columns, each bound to a property of the Friend-class. As the ID-property shouldn’t be visible to the user, the Headers and Items of this BoundField are using the CSS-class "invisibleColumn". This class simple set’s the width to zero and the display-property to none, so that this column is not visible to the user, but you can access it on a postback, e.g. to update the Friend-object in a database, where you’ll need the ID. On the page I’ve also set the font-family and font-size, as you can see below.

<style>
  .invisibleColumn
  {
    display: none;
    width: 0px;
  }
  body
  {
      font-family:Arial;
      font-size:12px;
  }
</style>

The next thing to do is to add the EventHandlers in the Codebehind-file. In the SelectedIndexChanged-Event the Text of the txtFriend-TextBox is set to the value of the second cell of the selectedRow. The second cell contains the FirstName. As the GridView is in an UpdatePanel with the TextBox, only this part of the Page is refreshed on the Clientside (via AJAX).

protected void FriendGridView_SelectedIndexChanged(…)
{
  // assign firstname
  if (FriendGridView.SelectedRow != null)
    txtFriend.Text = Server.HtmlDecode(
      FriendGridView.SelectedRow.Cells[1].Text);
  else
    txtFriend.Text = "";
}

To display some mouseover-effects on the GridView and to allow selection by clicking on a row, the RowDataBound-Eventhandler is necessary. There some Javascript is added to each row of the GridView.

protected void FriendGridView_RowDataBound(…)
{
  if (e.Row.RowType != DataControlRowType.DataRow)
    return;

 e.Row.Attributes["onmouseover"]="this.style.cursor=’hand’;"
 +"this.originalBackgroundColor=this.style.backgroundColor;"
 +"this.style.backgroundColor=’#bbbbbb’;";

 e.Row.Attributes["onmouseout"] =
 "this.style.backgroundColor=this.originalBackgroundColor;";

 e.Row.Attributes["onclick"] =
 ClientScript.GetPostBackClientHyperlink(this.FriendGridView,
  "Select$" + e.Row.RowIndex);
}

The most important on the snippet above is the last line that adds the onclick-Attribute to the row. With this attribute and the value of it the row is selected via click and doesn’t need a Select-Button, like the default-GridView needs to select a row. When a row is clicked, the SelectedIndexChanged-Event is automatically triggered by that JavaScript and the txtFriend-TextBox is set to the selected firstname in the Eventhandler for SelectedIndexChanged.

To make it really working, the last thing to do is to add the EnableEventValidation-Attribut to your page and set it to false. This allows the JavaScript from the snippet above to invoke the SelectedIndexChanged-Event. As an alternative to setting this attribute to false you can take a look at the RegisterForEventValidation-Method of ClientScriptManager that you can call in the Render-Method of your page.

<%@ Page Language="C#" EnableEventValidation="false" …

That’s all. Now let’s take a look at the dropdown. Just fill it in the Page_Load-Event with the same data as the string-concatenated dropdown before.

protected void Page_Load(object sender, EventArgs e)
{
  PseudoFriendDataAccess da = new PseudoFriendDataAccess();
  List<Friend> friendList = da.LoadAllFriends();

  FriendGridView.DataSource = friendList;
  FriendGridView.DataBind();
}

Below you see the created multicolumn-Dropdown. I’ve selected Christoph and reopened the DropDown again. The TextBox displays his firstname and the GridView shows the selected row.

ajaxExtenderWithGridViewDropDown

Make the multicolumn-DropDown usable for many rows

If you’ve more rows, the dropDownList should be scrollable. To add scrollsupport, simply extend the Style-Property of the FriendDropDown-Panel and add an overflow- and a max-height-attribut. Set the overflow-attribut to scroll, and the max-height to a value of your choice.

<asp:Panel runat="server" ID="FriendDropDown"
  Style="max-height:150px;overflow:scroll;
         display:none; visibility: hidden;">

For test-purposes I’ve just filled the FriendDropDown-GridView with more than 4 Rows to get the scroll behavior. In Firefox it looks great.

scrollableFireFoxDropDown

Unfortunately Internet Explorer 7 doesn’t calculate the size of the vertical scrollbar to the Panel (it’s a div-tag in HTML) containing the GridView. So in Internet Explorer 7 you won’t see the total of the last column. Instead of that you have to scroll horizontally.

scrollableIE7DropDown

To get very simply rid of that, I’ve added a dummy-column as the last column (and so the column on the right side) to the GridView that has a width of 15px. 15px is about the width of the vertical scrollbar.

<Columns>
<asp:TemplateField ItemStyle-Width="15px" />
</Columns>

Now that dummy-column will be behind the vertical scrollbar and the user is able to see all necessary columns.

scrollableIE7BetterDropDown

If the user scroll’s to the right with the horizontal scrollbar, he just sees the dummy-column.

scrollableIE7BetterDropDown2

So that’s all.

I think you can develop a control out of that stuff if necessary.

If you have additional information about developing multicolumn-Drowdowns or any feedback, or if you’re interested in the source code, just write a comment or a mail via the contact-formular on my homepage.

If you found this article useful, just feel free to kick it for me:

kick it on DotNetKicks.com

Thanks a lot. :-)