Contents tagged with Silverlight

  • Containing Silverlight Lists and DataGrids in the Browser Window

    In a typical Silverlight line-of-business application we have Lists, Grids, DataGrids, and StackPanels.  We populate a list and it flows down and off the browser page.  When we have a ScrollViewer, it will scroll the whole page including edit controls and graphics and not just the list that's tall and flowing off the page.  The good news is that we can easily contain the list in the viewable area with the few simple steps listed below.

    1. Remove the ScrollViewer from the page if it exists.
    2. Contain all upper area graphics and edit controls in a RowDefinitions of explicit size or Auto.
    3. Contain the lower List(s) in a final Grid RowDefinition with the Star notation to fill the remainder of the window using the outer-most Grid as a parent container.
    4. Optionally specify for the List properties,  VerticalAlignment="Top" and VerticalContentAlignment="Stretch".  Otherwise the List and its borders will stretch to the bottom of the screen even if it has no items.  Either way may be preferred. 

    The following screen shots demonstrate this with a simple GridSplitter to size either side.  Notice the List on the left is using two rows compared to the list on the right.  The list on the right isn’t flowing to the bottom and uses only one row.  Both lists flow to the bottom of the browser window and no further, regardless of the number of items.

    XAML rocks
    .
    -Vince


    Runtime:

      

    Designer:

      

     

    XAML:

        <Grid x:Name="LayoutRoot"
              Background="#FFCEA1A1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="50" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <sdk:Label Content="List 1"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       FontSize="16"
                       FontWeight="Bold" />
            <sdk:Label Grid.Column="2"
                       Content="List 2"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       FontSize="16"
                       FontWeight="Bold" />
            <ListBox Grid.Row="1"
                     Grid.RowSpan="2"
                     Name="listBox1"
                     Margin="10" />
            <sdk:GridSplitter Grid.Row="1"
                              Grid.Column="1"
                              Width="10"
                              HorizontalAlignment="Stretch"
                              Grid.RowSpan="2" />
            <ListBox Grid.Row="2"
                     Grid.Column="2"
                     Name="listBox2"
                     Margin="10"
                     VerticalAlignment="Top"
                     VerticalContentAlignment="Stretch" />
            <sdk:Label Grid.Row="1"
                       Grid.Column="2"
                       Content="(Edit Controls)"
                       FontSize="16"
                       FontWeight="Bold"
                       HorizontalAlignment="Center" />
        </Grid>
    </UserControl> 


    Code-Behind:

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        listBox1.Items.Clear();
        listBox2.Items.Clear();

        for (int i = 1; i <= 100; i++)
        {
            string listItem = "List Item " + i.ToString();

            listBox1.Items.Add(listItem);
            listBox2.Items.Add(listItem);
        }
    }

     

     

  • Videos from My Past Presentations

    Shawn Weisfeld has recorded several presentations that I've been fortunate enough to present at various times.  Shawn also stalks other active community speakers with that camera of his.  Check out the complete list on the INETA Champs live site at http://newlive.ineta.org/.  That's more than enough video content to fill a Saturday night or skip the Monday night football.


    Here is a list of my presentations at http://newlive.ineta.org/Presentation/Speaker/26

     

    Nuts and Bolts in XAML Part 1 - 7/6/2010
    http://newlive.ineta.org/Presentation/ViewVideo/110


    Nuts and Bolts in XAML Part 2 - 8/3/2010
    http://newlive.ineta.org/Presentation/ViewVideo/122


    Working with Data in Silverlight - 6/18/2010
    http://newlive.ineta.org/Presentation/ViewVideo/106


    Understanding Databinding with XAML in WPF and Silverlight - 3-2-2010
    http://newlive.ineta.org/Presentation/ViewVideo/36
    http://newlive.ineta.org/Presentation/ViewVideo/37
    http://newlive.ineta.org/Presentation/ViewVideo/38

  • RIA Services - Solutions to 'The remote server returned an error: NotFound'

    Isn't it great when the answers are out there?  I finally got a Google hint and overcame this one.  So here are a few reasons that I encountered and overcame this error.  We can easily reproduce (and often fix) this error.  This occurs on the asynchronous return from a Silverlight 4 to RIA services.  It's as if for any of the few reasons it fails, the call just gets aborted and we get a head-scratching "Not Found".  We can sometimes even hit a debugger breakpoint in the Domain Service that gets the IQueryable call and wonder why the server appears to work in the debugger.

    Here are a few suggestions to help.

    1. Returning too much data for the object graph.  Solution: Edit the 'maxItemsInObjectGraph' setting in the web.config.
    2. Throwing an unhandled error on the service logic.  It can't get back to the client.  Solution: Comment out logic and see if the call succeeds.
    3. Solution: Only enable Anonymous authentication.  The request can then avoid authentication errors and possibly return successfully.  This one got me again tonight when deployed a new client’s project for the first time.  It also confused several of us at the Dallas Silverlight and WP7 DevCamp that I mentored at the other day.   The project will work great in the local development server but when deployed to IIS, we get a Not Found error.  So try disabling the Forms and Basic Authentication with only Anonymous enabled.  I'm convinced that this is the most likely reason for most people.

    Hope this helps others with this unintuitive error message....Hopefully it's "Now Found".

    -Vince

  • Silverlight OOB - CheckAndDownloadUpdateAsync

    I’ve been looking at the Silverlight Out-Of-Browser support and the easy update feature.  In the current version, we’re given the method, CheckAndDownloadUpdateAsync().  This method does a lot for us but is rather limited.  With an asynchronous method and no parameters, what can we expect?  With a huge team in Redmond working for us and trying to meet deadlines, we get what we get.  In the spirit of sharing, here’s what I see so far.

    Features:

    • Detect network connectivity (and sometimes it fails miserably…)
    • Connect to the original authorized URL that it was installed from
    • Download the new XAP file and compare the current version against the downloaded version from the manifest
    • Detect the current Silverlight version vs. the new version’s Silverlight version
    • If a failure occurs, failure exception types are provided for recovery such as “PlatformNotSupportedException”

    Limitations:

    • Can’t interrupted the request.  So when it times out, we wait for it.
    • Can’t download the update and make it optional to install and replace the currently running XAP.  A flag to just detect a newer version would be better.  This would allow the UI to show the current version and available update version.
    • Returns a false for the “UpdateAvailable” property for several reasons such as the new XAP is not signed, is a newer Silverlight Version, or various other errors.  We must then look at *ALL* of the possible error class types placed in the error collection.  A bunch of try-catches are therefore necessary.  The try-catches do the job as long as we have every possible error type in a catch.  An enum for the actual error reason may be better.
    • Can’t revert to a previous stable version and have it install over a newer bad version.  It makes sense, but real development teams have recovery plans when updating production versions.

    Q: What if we want to make the newer XAP file replacement optional?   Here are some thoughts.

    Not everyone wants to increase the newer version number for a rollback version.  The Silverlight client can call the web server to get the new version number using other networking connectivity options.  The server call could be as complicated as a WCF service, ASMX service, Web Method call, or an HTTPRequest to get the online version information.  Getting the version from the server could be as complicated as reading the newer version’s manifest file, read the new file date and time, or newer folder date and time.  It could be as simple as getting a text file that has only the expected Silverlight version and the new XAP version.  If the major or minor version is different, then the Silverlight client can act appropriately such as displaying an update message box or button to perform the CheckAndDownloadUpdateAsync() call.  The only issues I can imagine would be security issues of calling back to a “different” server where a ClientAccessPolicy.xml file is required.  If it were HTTPS from the install, the new version check call may to an HTTP.  The different server could also include “WWW” or not include it and therefore require the ClientAccessPolicy.xml file.  The simple version text file can be automatically generated in the Silverlight application build script.  This way DEV, QA, and Production can generate and test it easily without requiring the file to be edited every time it gets deployed.  This may not allow a previous version to replace a new bad version (users install updates with the Silverlight plugin, not our code) but it does get closer so the installed version can stop working or corrupting data until they uninstall and reinstall the previous version.  A rollback with a version increase is easier so we can just call CheckAndDownloadUpdateAsync for the actual rollback.  Again, these are just some thoughts to get closer to real-world deployments.

    A Silverlight OOB launcher debugger is available. More information: http://blogs.msdn.com/b/silverlight_sdk/archive/2010/04/10/sllauncher-error-messages.aspx

    Q: Needs some good code examples?  A few really good Silverlight OOB blog entries can be found here: http://nerddawg.blogspot.com/search/label/Out-of-browser

    This should give some food for thought until we get a more robust CheckAndDownloadUpdateAsync method.

    -Vince

     

  • Dallas XAML UG Samples for Data Binding

    The Dallas XAML User Group is holding their second meeting on April 6th 2010.  We will be spending most of the time on our laptops practicing data binding techniques for WPF and Silverlight.  The completed samples are uploaded and ready to review before the meeting.  The theme for samples is a GoldWing reseller.  Can you guess which sweet Orange motorcycle that I own and love to ride around Texas, Oklahoma, and Arkansas with my wife?

  • WPF Routed Events – Bubbling Several Layers Up

    Recently, the WPF question of the day for me was how to bubble up a toggle button event through several layers with less code.  In WPF we can easily add layers without worrying about wiring up delegates for each level.

    Most of the blogs and MSDN help pages were detailed but not obvious.  This simple example shows how a registered event in the lowest level user control can bubble up for a top level parent to handle the event.  The example bubbles up an event from the QueueButton user control (Level 4) to View2 (Level 3) , then View1 (Level 2), then the top parent Window1 (Level 1) .  There is no code behind nor any delegates to maintain at any level except the firing control and any listeners.  We should be able to add any number of views in the visual tree and still avoid any extra work.  The event is a Bubble event and not Tunnel, but that is an example for another day.  Tunneling can be thought of (informally) as a falling bubble from the top level of the visible tree to the source.  This lets each level receive the event like bubble up does, but knowing that the parent control had an option of acting on the event.

    I hope this simple example helps someone keep the WPF code clean and simple.

    -Vince

    Window1 - Level 1 - The Top Level Listener:

    XAML:

    <Window x:Class="Routed.Window1"
        xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
        xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
        Title="ToggleButton Event Bubbling Example" 
        xmlns:local="clr-namespace:Routed" 
        local:QueueButton.EnableQueue="Window_EnableQueue">
        <Grid>
            <StackPanel>
                <TextBlock Text="Window1" HorizontalAlignment="Center" />
                <TextBlock x:Name="ToggleStateTextBlock" HorizontalAlignment="Center" Margin="10" FontSize="14" />
                <local:View1 />
            </StackPanel>
        </Grid>
    </
    Window>

     

    The Single Code-Behind Method:

    private void Window_EnableQueue(object sender, RoutedEventArgs e)
    {
        QueueButton queueButton = e.OriginalSource as QueueButton;
        if (null != queueButton)
            ToggleStateTextBlock.Text =
    "Toggle Button IsChecked = " + queueButton.IsChecked.Value.ToString();
    }

     

    View1 - Level 2:  (No Code Behind in View1)

    <UserControl x:Class="Routed.View1"
        xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
        xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
        Height="200" Width="200"
        Background="Peru"
        xmlns:local="clr-namespace:Routed">
        <Grid>
            <TextBlock Text="View1" HorizontalAlignment="Center" />
            <local:View2 />
            </Grid>
    </
    UserControl>

     

    View2 - Level 3: (No Code Behind in View2)

    <UserControl x:Class="Routed.View2"
        xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
        xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
        Height="150" Width="150"
        Background="ForestGreen"
        xmlns:local="clr-namespace:Routed">
        <Grid>
            <TextBlock Text="View2" HorizontalAlignment="Center" />
            <local:QueueButton />
        </Grid>
    </
    UserControl>

     

    QueueButton - Level 4 - The Event Source

    QueueButton XAML:

    <ToggleButton x:Class="Routed.QueueButton"
        xmlns
    =http://schemas.microsoft.com/winfx/2006/xaml/presentation
        xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
        Height="60" Width="100">
        <Grid
    >
            <TextBlock Text
    ="Toggle This!!!" />
        </Grid
    >
    </
    ToggleButton>

     

    QueueButton Code Behind:

    using System.Windows;
    using System.Windows.Controls.Primitives;
    namespace Routed
    {
            public partial class QueueButton : ToggleButton
            {
                public static readonly RoutedEvent EnableQueueEvent;

                static QueueButton()
                {
                    QueueButton.EnableQueueEvent = EventManager.RegisterRoutedEvent("EnableQueue"
                    RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(QueueButton));
                }

                public event RoutedEventHandler EnableQueue
                {
                    add { AddHandler(QueueButton.EnableQueueEvent, value); }
                    remove { RemoveHandler(QueueButton.EnableQueueEvent, value); }
                }

                public QueueButton()
                {
                    InitializeComponent();
                }
                protected override void OnChecked(RoutedEventArgs e)
                {
                    RaiseEvent(
    new RoutedEventArgs(QueueButton.EnableQueueEvent, this));
                }

                protected override void OnUnchecked(RoutedEventArgs e)
                {
                   RaiseEvent(
    new RoutedEventArgs(QueueButton.EnableQueueEvent, this));
                }
            }
    }

     

  • DallasXAML.com – A New User Group for Silverlight, WPF, XBAP, etc.

     

    The Dallas XAML User Group               

                   http://DallasXAML.com

     

    I’ve devoted much of last month to starting the DallasXAML User Group.  I finally got back into user group management after 2 years away from leading the Dallas C# SIG.  Now I’m having fun getting a Silverlight/WPF user group going strong for the Dallas / Ft. Worth community.  Our first meeting was March 3rd at the Improving Enterprises offices in North Dallas.  We had about 25 to 35 attendees in the first meeting and it went well.  We covered the most important topic that everyone should understand well – data binding.

     

    So I chose the XAML user group so we can get together for a common group improvement in the Dallas / Ft. Worth area and learn cross-technology information that we can use now.  It is not a lecture hall.  The great thing is that we’ll provide hands-on experience with most every meeting.  The goal is to get the experience that we can use the next work day.  I unfortunately broke that rule by speaking all through the first meeting, but next month is part two with more hands-on data binding.

     

    The differentiation is this group concentrates on XAML, not Silverlight or Windows Client alone.  What we learn in one area, we gain for all areas.  That includes the Silverlight for Windows Phone 7 coming later this year.  Next year it may be Windows Phone 8, 9, or whatever. 

     

    I started developing WPF seriously almost a year ago.  I experienced the painful learning curve.  Anyone who reports that there isn’t a big learning curve either thinks in XAML before it was developed, is on the Silverlight or WPF development team, or has already conquered the learning and forgot the pain.  So I wanted to share the pain or make it easier for others – same thing.  I have found that the more I learn and use good disciplined techniques, the more interesting and rewarding development is again.

     

    A few months ago, I was sitting in the iPhone development session at the Dallas C# SIG.  After the meeting, the audience was polled for future topics.  After a few suggestions, Silverlight got the big hands up.  That makes sense because it’s still the hot topic for many Microsoft developers.  So I surfed around and found that there aren’t enough user groups to help in this area.  I polled a few local group leaders and did the work to start the group.  This week I got a telerik controls licence and improved the site with some great controls, namely the RadHtmlPlaceholder control.  It provides a Silverlight control to show HTML in an IFrame-like area.  On DallasXAML.com, the newsletters and resource pages display in HTML because Silverlight just isn’t there yet.  I’m looking forward to a Silverlight XPS viewer with flow documents.  There are some good commercial version available, but this is a non-profit group. 

     

    The DallasXAML.com site points to many other resources such as podcasts and webcasts.  I would rather give them the credit than try to out-do them.  So check out the DallasXAML user group site and attend our meetings if you can.  We meet the first Tuesday of the month.

     

    -Vince

    DallasXAML User Group Leader

     

  • Debugging with VS2008 at the Dallas ASP.NET UG

    Some time back, I gave a talk at the Dallas ASP.NET User Group on the topic of "Debugging with Visual Studio 2008".  In case anyone can find the notes, slides, and demos useful, they are located at http://www.dallasasp.net/Meetings/238.aspx.  Some things have changed since Silverlight has gone RTW (Released To Web/World).

    At the meeting, we discussed ways to think like an efficient debugging developer and then we walked through the demos to see it in action.  We walked performed some debugging actions and looked at a few things that a typical debugging session doesn't encounter.  We looked at the rarely used attributes that are good for debugging, IE Developer toolbar, and Firefox's FireBug.

    I will repeat some advice that I was given over 13 years ago.  Anyone can work and produce but more valuable are people who solve problems.  Now that's good debugging advice.  This was one of my favorite talks and I hope the demos will be helpful to others.  The demo concept entails a meeting RSVP system.  The data is random based on the time but the numbers change just the same.

    Demos:

    RSVPSilverlightWeb: A simple ASP.NET web site with three example technologies: Standard ASP.NET AJAX, JSON, and a Silverlight control.  We performed some debugging with the three components that are located on a single web page.

    RSVPModule:  An HTTP Module used in the website to display the page load time.

    RSVPHandler: An HTTP Handler that will perform work for urls with the "RSVP" extension such as ShowDallasASPNetUG.rsvp.  I noticed that the demo zip file does not have the extremely simple RSVP application that was deployed to my IIS.  You can reproduce this extremely simple demo.  It is an ASP.NET application with a simple default.aspx and nothing added.  The web.config has one line added to to the httpHandlers node as shown below.  This register the handler to call the handler for debugging.

             <add verb="*" path="*.rsvp" type="RSVP.RSVPHandler" />
        </httpHandlers>

    RSVPSilverlight: This is a Silverlight component that uses a web service file, WebServiceSilverlight.cs, in the RSVPSilverlightWeb website project.  Beware - this was the beta2 version without considerations for cross-domain web service calls.  To get it working properly with the RTW version, we follow the link at
    http://msdn.microsoft.com/en-us/library/cc197955(VS.95).aspx and re-create the service reference in the Silverlight control.

    RSVPGadget: A Windows Vista Gadget using our existing WCF with JSON that is consumed on the RSVPSilverlightWeb page.  The files that are in the RSVPGadget files are copied to a folder such as

    "C:\Users\[user]\AppData\Local\Microsoft\Windows Sidebar\Gadgets\RSVP.gadget".

    Resources:

    The Ultimate Debugger (Tess Ferrandez)

    http://blogs.msdn.com/tess

    Books

    Debugging Strategies for .Net Developers
      Apress - Darin Dillon

    Debugging .NET 2.0 Applications
      MSPress - John Robbins

    Stay Current on ASP.NET and Silverlight 2.0

    http://www.asp.net/downloads/vs2008/

    Javascript Debugging

    http://weblogs.asp.net/scottgu/archive/2007/07/19/vs-2008-javascript-debugging.aspx

    Debugging ASP.NET AJAX Applications

    http://www.asp.net/learn/ajax/tutorial-06-cs.aspx

    Firebug: (Tutorial)

    http://michaelsync.net/2007/09/08/firebug-tutorial-overview-of-firebug

    Production Debugging

    http://blogs.msdn.com/tom/archive/2008/07/15/debugging-asp-net-on-a-production-server-101.aspx

    WinDbg + SOS

    http://support.microsoft.com/kb/892277

    More on Vista Gadgets:

    http://www.microsoft.com/technet/scriptcenter/topics/vista/gadgets-pt1.mspx

    http://msdn.microsoft.com/en-us/magazine/cc163370.aspx

    The Vista Gadget:

    TheVistaGadget

    The Demo Web Page:

    TheWebPage

  • Silverlight 2.0 Webcasts at ISV Innovation

    Bill Lodin is presenting a very informative 4-part webcast series on Silverlight 2.0 (beta 1). 
        http://www.isvinnovation.com/Directory/Description.aspx?EventId=424

    Microsoft Silverlight 2.0


    Part: 1 - Technical Drill-down
    Part: 2 - The UI Framework
    Part: 3 - Networking Support
    Part: 4 - Advanced Topics

    We can just pretend that he dropped by for lunch to show the new features that will RTM later this year.

    -Vince