Rockford Lhotka

 Wednesday, March 25, 2009

Google tells me that issues with the Silverlight ComboBox control are widespread and well known. It also tells me that there are few solid solutions out there if you want data binding to work with the Silverlight ComboBox in a simple, reliable manner.

Perhaps the best post on the topic is this one, but this particular code example doesn’t work in all cases (specifically not inside a DataTemplate, and as a form loads and gets async data).

After wasting more time than I care to consider, I believe I have a more complete solution. Though it isn’t perfect either, it does appear to work nicely with CSLA .NET NameValueListBase objects, and inside DataTemplate elements, which is really what I was after.

As others have pointed out, the solution is to subclass ComboBox and add SelectedValue and ValueMemberPath properties to the control. The trick is to catch all the edge cases where these new properties, and the pre-existing SelectedItem and Items properties, might change. I may not have them all either, but I think I handle most of them :)

To use the new control, you need to bring in the namespace containing the control, and then use XAML like this:

<this:ComboBox Name="ProductCategoryComboBox"
               ItemsSource="{Binding Source={StaticResource ProductCategories},Path=Data}"
               SelectedValue="{Binding Path=CategoryId, Mode=TwoWay}"
               ValueMemberPath="Key"
               DisplayMemberPath="Value"/>

At least in my code, you must set the ValueMemberPath, though I’m sure the code could be enhanced to avoid that requirement. The bigger thing is that the SelectedValue binding must have Mode=TwoWay or the binding won’t work reliably. Even if you are using the ComboBox for display-only purposes, the Mode must be TwoWay.

Also I should point out that this XAML is using the CslaDataProvider control to get the data for the ItemsSource property. You could use other techniques as well, but I like the data provider model because it shifts all the work into XAML, so there’s no code required in the presentation layer. The ProductCategories resource is a CslaDataProvider control that retrieves a NameValueListBase object containing a list of items with Key and Value properties.

Here’s the control code:

public class ComboBox : System.Windows.Controls.ComboBox
{
  public ComboBox()
  {
    this.Loaded += new RoutedEventHandler(ComboBox_Loaded);
    this.SelectionChanged += new SelectionChangedEventHandler(ComboBox_SelectionChanged);
  }

  void ComboBox_Loaded(object sender, RoutedEventArgs e)
  {
    SetSelectionFromValue();
  }

  private object _selection;

  void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
  {
    if (e.AddedItems.Count > 0)
    {
      _selection = e.AddedItems[0];
      SelectedValue = GetMemberValue(_selection);
    }
    else
    {
      _selection = null;
      SelectedValue = null;
    }
  }

  private object GetMemberValue(object item)
  {
    return item.GetType().GetProperty(ValueMemberPath).GetValue(item, null);
  }

  public static DependencyProperty ValueMemberPathProperty =
    DependencyProperty.Register("ValueMemberPath", typeof(string), typeof(InventoryDemo.ComboBox), null);

  public string ValueMemberPath
  {
    get
    {
      return ((string)(base.GetValue(ComboBox.ValueMemberPathProperty)));
    }
    set
    {
      base.SetValue(ComboBox.ValueMemberPathProperty, value);
    }
  }

  public static DependencyProperty SelectedValueProperty =
    DependencyProperty.Register("SelectedValue", typeof(object), typeof(InventoryDemo.ComboBox),
    new PropertyMetadata((o, e) =>
    {
      ((ComboBox)o).SetSelectionFromValue();
    }));

  public object SelectedValue
  {
    get
    {
      return ((object)(base.GetValue(ComboBox.SelectedValueProperty)));
    }
    set
    {
      base.SetValue(ComboBox.SelectedValueProperty, value);
    }
  }

  private void SetSelectionFromValue()
  {
    var value = SelectedValue;
    if (Items.Count > 0 && value != null)
    {
      var sel = (from item in Items
                 where GetMemberValue(item).Equals(value)
                 select item).Single();
      _selection = sel;
      SelectedItem = sel;
    }
  }

  protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
  {
    base.OnItemsChanged(e);
    SetSelectionFromValue();
  }
}

It seems strange that the standard control doesn’t just do the right thing – but we must live in the world that is, not the world we would like to see…

Wednesday, March 25, 2009 10:01:05 AM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Sunday, March 22, 2009

I have made CSLA .NET 3.6.2 RC0 available for download.

Version 3.6.2 includes a number of bug fixes, but more importantly includes a number of new features and enhancements based on feedback from users of version 3.6. Highlights include:

  • For both Windows and Silverlight
    • New methods on the ObjectFactory base class to better enable creation of a DAL object
    • Better support for lazy loaded fields, where an exception is thrown if the field is mis-used accidentally (thus reducing bugs)
    • ErrorDialog control for WPF and Silverlight to enable XAML-only handling of exceptions from CslaDataProvider
    • CslaDataProvider now has a Saved event to simplify some UI scenarios
    • RegisterProperty() now accepts a lambda expression to identify the property name, allowing the compiler to check the name, and avoiding the use of the string literal
    • MobileDictionary type, so you can create a dictionary that serializes between Silverlight and .NET
  • For Silverlight only
    • Better type name resolution, so you can now specify a type by "Namespace.Class, Assembly" without supplying the generic "Version=..." text
    • New InventoryDemo sample project (C# only right now - it is a work in progress)
    • Code snippets for async factory and data access methods

    Hopefully this is the final test release of 3.6.2, and I am planning for a final release on March 30 or 31 (before April Fool’s Day :) ). If you are using 3.6.0 or 3.6.1, please download and test this release and let me know if you encounter any issues.

  • Sunday, March 22, 2009 5:33:41 PM (Central Standard Time, UTC-06:00)  #    Disclaimer

    Many people have asked me for the status of a CSLA .NET for Silverlight ebook. I may yet write such an ebook, but I am trying something new and different first – a 7 part video series covering CSLA .NET for Silverlight.

    Each video will be roughly 40 minutes in length, and the topics include:

    1. Introduction to CSLA .NET for Silverlight
    2. Creating a basic Silverlight and CSLA .NET for Silverlight application
    3. Implementing client-only architectures (calling remote services)
    4. Implementing n-tier archtiectures (using a remote data portal)
    5. Implementation of all CSLA .NET business object stereotypes
    6. Data Access in n-tier applications
    7. Authentication and authorization in CSLA .NET for Silverlight

    This totals to nearly 5 hours of content, with a mix of lecture and demo (though heavy on the demo).

    My current plan is to sell the videos through my online store, allowing purchasers to download the videos so they can be watched offline. The files will be quite large, but once downloaded, you’ll be able to watch them offline and I think that’s preferable to a streaming approach (though I’m open to feedback – would streaming be better?).

    While allowing downloads of the files may invite piracy, I’ll take that risk. I’m sure my ebooks have suffered from some piracy (some people are simply immoral), but I strongly believe that most counter-measures are easily defeated by the criminals and they absolutely complicate the lives of honest customers. The videos will cost more than the ebooks, as I’m basing my pricing on comparable video training, but I am hopeful that this won’t make the piracy issue worse. Unlike stealing from a “big publisher”, a lot of piracy and lack of actual sales just means I won’t be able to afford to create more videos or other content – the linkage between the criminal and me is direct – so I’m hopeful that the “casual pirate” will at least think twice before stealing from the guy who created the framework they are trying to learn :)

    As always though, I believe that most people are basically decent, and that this video series will have very real, tangible value to users of CSLA .NET for Silverlight (and CSLA .NET in general to some degree).

    To create the video series, I’ve hired a video producer and they’ll be doing the editing and production work. They also did all the lighting and camera work to film the live lecture parts of each segment, and what I’ve seen so far looks and sounds very nice! I’m using Camtasia to record the demo parts of each segment, and they’ll merge the lecture and demo content together to create each final segment. The live lecture parts were filmed in one of Magenic’s conference rooms, and I’m pretty pleased with the visual layout (it is somewhat like being in a classroom or at a conference).

    My current train of thought is to offer early adopters a discount, allowing you to download the segments as they become available. I think a discount is warranted, as the segments will be completed over a period of a few weeks, so there’s an element of "paying for future content” involved for any early adopters.

    Watch for the announcement of availability in the next very few short weeks!

    Sunday, March 22, 2009 5:33:34 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
     Friday, March 13, 2009

    I recently did a webcast on CSLA .NET 3.6 through Mike Benkovich’s Benkotips website.

    You can see all Mike’s webcasts, or you can go directly to the CSLA .NET webcast recording.

    This webcast is an overview of CSLA .NET, and includes about 35 minutes of demo where I walk through a CSLA .NET for Silverlight application.

    Friday, March 13, 2009 2:07:58 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
     Thursday, March 12, 2009

    Dunn Training is offering their excellent five day training class on CSLA .NET in San Francisco on May 4-8. They have some seats open, so if you are looking for training on CSLA .NET, and you are near San Francisco (or would like to be :) ), now’s the time to sign up!

    Thursday, March 12, 2009 8:15:23 PM (Central Standard Time, UTC-06:00)  #    Disclaimer

    When CSLA .NET 3.6.2 is released in a couple weeks, it will be sporting a slightly altered license and copyright notices, with the name Marimer, LLC.

    Marimer, LLC is my shiny new corporate entity, and it is now the owner of all versions of the CSLA .NET framework.

    This doesn’t change the terms of the license, nor should it have any effect on CSLA .NET or anyone’s use of CSLA .NET. It is simply a formal step I felt was necessary to protect myself and my family for legal liability reasons. Honestly, it is something I probably should have done years ago, but it is done now, so I can sleep better at night.

    At the moment I don’t plan to change anything beyond the copyright and ownership statements, and since I have sole control over Marimer, LLC, nothing changes in relation to the continued development of the CSLA .NET framework.

    Thursday, March 12, 2009 5:00:35 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
     Wednesday, March 11, 2009

    I have been working extensively with both WPF and Silverlight over the past many months. Not too long ago, my workstation started having trouble – specifically Visual Studio 2008 was crashing when trying to open XAML files. Not just crashing either; Visual Studio was disappearing in the blink of an eye.

    This started happening every now and then, and became more frequent until it was happening multiple times a day.

    After working with some Microsoft people to try and trace down the problem (which we never really did – as it is hard to attach a debugger or other diagnostic tool to VS after it disappears), they suggested I try this patch:

    https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=16827&wa=wsignin1.0

    (the *.msu are for Vista and Server 2008, and *.exe are for XP and Server 2003, and the x86 patch should be used for 64 bit machines too

    Update: For x64 users, you should install the x64 patch, and this will update the 32 bit CLR as part of the installation)

    This patch solved my problem. Just like that.

    Apparently this patch solves a wider set of problems related to stability when editing or working with XAML files in Visual Studio, and is a generally good thing to apply for developers working with WPF and Silverlight.

    Wednesday, March 11, 2009 6:01:23 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
     Monday, March 2, 2009

    I have put a new 3.6.2 release online for Windows and Silverlight. I am considering this a beta release, and am now moving toward final release of 3.6.2.

    Version 3.6.2 contains important bug fixes, and several enhancements to existing features based on feedback from people working with 3.6.1 so far. Highlights of the enhancements include:

    • For both Windows and Silverlight
      • New methods on the ObjectFactory base class to better enable creation of a DAL object
      • Better support for lazy loaded fields, where an exception is thrown if the field is mis-used accidentally (thus reducing bugs)
      • ErrorDialog control for WPF and Silverlight to enable XAML-only handling of exceptions from CslaDataProvider
      • CslaDataProvider now has a Saved event to simplify some UI scenarios
      • RegisterProperty() now accepts a lambda expression to identify the property name, allowing the compiler to check the name, and avoiding the use of the string literal
      • MobileDictionary type, so you can create a dictionary that serializes between Silverlight and .NET
    • For Silverlight only
      • Better type name resolution, so you can now specify a type by "Namespace.Class, Assembly" without supplying the generic "Version=..." text
      • New InventoryDemo sample project (C# only right now - it is a work in progress)
      • Code snippets for async factory and data access methods

    At this point 3.6.2 is feature-complete and is in test mode. Only bug fixes will be added at this point, with the plan being to release in the next couple weeks.

    Monday, March 2, 2009 5:02:52 PM (Central Standard Time, UTC-06:00)  #    Disclaimer

    My article providing an overview of some of the parallel and concurrent programming features coming in .NET 4.0 is online:

    Parallel and Concurrency Futures for Microsoft Developers

    Monday, March 2, 2009 2:34:11 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
     Thursday, February 19, 2009

    Setting up any type of n-tier solution requires the creation of numerous projects in the solution, along with appropriate references, configuration and so forth. Doing this with a Silverlight application is complicated slightly because Silverlight and .NET projects are slightly different (since they use different compilers, runtimes, etc). And sharing code between Silverlight and .NET projects complicates things a bit more, because the same physical code files are typically shared between two different projects in the solution.

    CSLA .NET for Silverlight makes it relatively easy to create powerful n-tier applications that do share some code between the Silverlight client and the .NET server(s). Even though CSLA .NET does solve a whole host of issues for you, the reality is that the solution still needs to be set up correctly.

    Here are the basic steps required to set up an n-tier CSLA .NET for Silverlight solution:

    1. Create a new Silverlight application project
      1. Have Visual Studio create a web application for the Silverlight project
    2. Add a new Silverlight Class Library project (this is your business library)
    3. Add a new .NET Class Library project (this is your business library)
    4. Use the Project Properties windows to set the Silverlight and .NET Class Library projects to use the same namespace and assembly name
      image
      image
    5. Remove the Class1 files from the Silverlight and .NET Class Library projects
    6. (optional) Add a .NET Class Library project to contain the data access code
    7. Set up references
      1. The Silverlight application should reference Csla.dll (for Silverlight) and the Silverlight Class Library
      2. The Silverlight Class Library (business) should reference Csla.dll (for Silverlight)
      3. The ASP.NET Web application should reference Csla.dll (for .NET), the .NET Class Library (business) and the .NET Class Library (data)
      4. The .NET Class Library (data) should reference Csla.dll (for .NET) and the .NET Class Library (business)
      5. The .NET Class Library (business) should reference Csla.dll (for .NET)
        image
    8. Add your business classes to the .NET Class Library (business)
      1. Link them to the Silverlight Class Library (business)
      2. Use compiler directives (#if SILVERLIGHT) or partial classes to create Silverlight-only or .NET-only code in each Class Library
    9. Configure the data portal
      1. Add a WcfPortal.svc file to the ASP.NET web application to define an endpoint for the Silverlight data portal
      2. Add a <system.serviceModel> element to web.config in the ASP.NET web application to configure the endpoint for the Silverlight data portal
      3. Add any connection string or other configuration values needed on the server to the web.config file
      4. Add a ServiceReferences.ClientConfig file to the Silverlight application and make sure it has an endpoint named BasicHttpBinding_IWcfPortal pointing to the server

    This isn’t the simplest or most complex option for creating a CSLA .NET for Silverlight solution. You could use CSLA .NET for Silverlight to create a client-only application (that’s the simplest), or a 4-tier application where there is not only a web server in the DMZ, but also a separate application server behind a second firewall. I do think that the model I’ve shown in this blog post is probably the most common scenario however, which is why this is the one I chose to outline.

    Thursday, February 19, 2009 4:24:58 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
     Tuesday, February 10, 2009

    A ridiculously long time ago I was in a meeting at Microsoft, sitting next to Ted Neward. As you may know, Ted lives in both the Java and .NET worlds and kind of specializes in interop between them.

    Somehow (and I don’t remember the specifics), we got to talking about object serialization and related concepts like encryption, signing and so forth. It turned out that Java had a library of wrapper types that worked with the serialization concept to make it very easy to sign and encrypt an object graph.

    Thinking about this, it isn’t hard to imagine this working in .NET, and so I whipped up a similar library concept. I’ve used it from time to time myself, but never quite got around to putting it online for public consumption. Until now:

    Download the SerializationWrapper solution

    The download includes nunit tests, so you can figure out how to use it pretty easily by looking at those.

    For example, to sign a serializable object graph, just do this:

    SignedWrapper<string> wrapper = new SignedWrapper<string>(data, hashKey);

    You can then send the wrapper over the network as long as it is serialized using the BinaryFormatter or NetDataContractSerializer, and on the other end you can make sure it hasn’t been tampered with by verifying the signature:

    if (wrapper.Verify(hashKey))

    Of course the really tricky part is key exchange. How did both ends of the process get access to the same hashKey value? That’s outside the scope of my library, and frankly that is the really hard part about things like security…

    In fact, if you look inside the code for the various wrapper classes, you’ll find that I’m just delegating all the interesting work to the .NET cryptography subsystem. By using the various wrappers together you can do asymmetric public/private keys, symmetric keys. You can do signing, and encryption. I think I now cover all the different algorithms supported by .NET – in one nicely abstract scheme.

    Also, if you look inside the solution you’ll see a compression wrapper. That was an experiment on my part, and I really didn’t find the result satisfying. My thought was that you’d wrap your object graph (maybe after it was encrypted and signed) in the compression wrapper, and then that would be serialized to go over the wire.

    But it turns out that there are two flaws:

    1. Serializing the compressed data makes it quite a bit bigger, and you are better off transferring the CompressedData value from the wrapper rather than allowing the wrapper itself to be serialized.
    2. More importantly, compressing encrypted data doesn’t work well. Encrypted data is pretty random, and the two compression algorithms included in .NET don’t do a particularly good job of compressing that data. I don’t know if other algorithms are better at compressing encrypted data, but I was disappointed with the results I found here.

    In any case, I’ve found the crypto wrapper classes to be generally useful in abstracting most of the complexity of dealing with the .NET crypto subsystem, and I thought I’d share the code in case anyone else can find it useful as well.

    Tuesday, February 10, 2009 3:24:10 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
     Thursday, February 5, 2009

    I have run across a couple really interesting items in the Silverlight area recently, and I’d like to call some attention to both of them.

    First is a tool that compresses xap files called XapOptimizer. Right now you can try it online – upload your xap, then download a compressed result. I’ve done this with a couple of my xap files and the size difference is quite remarkable. I assume it will be a product you can work into your build script at some point.

    Second is something totally different: a browsable pattern library of UI patterns. This is really interesting, and potentially very useful, because it pulls together real-world examples showing various implementations of the patterns, as well as providing some good motivation and explanation about each. What’s even better, is that this is written in Silverlight. But the really impressive part of this is the effort that must have gone into collecting and organizing all the data for the patterns.

    Thursday, February 5, 2009 9:16:16 PM (Central Standard Time, UTC-06:00)  #    Disclaimer