Rockford Lhotka

 Monday, October 19, 2009

Microsoft has made Visual Studio 2010 and .NET 4.0 Beta 2 available for download to MSDN subscribers, with general availability soon. VS10 includes a lot of really nice features over VS2008, and I’m personally very excited to see the Beta 2 release.

I’ve made a pre-alpha CSLA .NET “4.0” available for download as well. This is really just the version 3.8.0 code (somewhere between beta 1 and beta 2) that I’ve updated to build under Visual Studio 2010 with .NET 4.0.

Over the next few months I’ll continue to release updates to version 4.0 that take advantage of the .NET 4.0 features, but I wanted to make sure there was a version online that builds with VS10 as soon as possible, so this is it – enjoy!

Monday, October 19, 2009 1:41:33 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Tuesday, October 13, 2009

A lot of organizations rely on Gartner for valuable advice. Personally though, I remember a point in the mid-90’s where Gartner pronounced that Unix would be the dominant operating system long before 2009. Of course actual Unix is a total non-issue, having destroyed itself through fragmentation. Linux is still very meaningful, but that wasn’t what Gartner was talking about…

So when Gartner speaks, people listen – but if people are smart they’ll take what’s said with a big pile of salt.

Gartner apparently just came out with some thoughts on Windows 7. Mary Jo Foley has a summary.

And some of what they say rings true. Businesses really are more conservative than consumers about adopting new operating systems. So when Gartner talks about the lack of adoption and slow movement at the corporate level I tend to agree.

But Windows 7 really is a different release from what we’ve seen in many years. The caution expressed around maturity of the product, and shifting to 64 bit deployments is, I think, misplaced.

I can honestly say that I’ve never seen Windows be so smooth, and provide such comprehensive driver support before official launch. Remember, it doesn’t really come out until later this month, but Windows 7 64 bit is already more compatible with my computer than Vista.

Sure, an enterprise does need to run through a testing period, especially if they are upgrading from Windows 2000 or XP. There are changes, as you’d expect given that Win2k and XP are nearly a decade old. But 99.9% of the changes in Win7 are for the better – making the user’s life better, and the network/system admin’s life better.

My recommendation however, is for organizations and individuals to be aggressive in moving to Windows 7. This is because the transition is the smoothest I’ve seen in nearly 20 years of working with Windows, and the user productivity and sheer enjoyment are the highest I’ve seen since Windows 98SE.

(disclaimer: I don’t own Microsoft stock, so my recommendation here is based purely on my personal enthusiasm for Windows 7 and how much more fun my computers have been since I upgraded)

Tuesday, October 13, 2009 11:07:10 AM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Monday, October 5, 2009

One of the new features in CSLA .NET 3.8 is the ability to use the data annotation attributes from System.ComponentModel.DataAnnotations.

The DataAnnotations namespace was added in .NET 3.5 SP1, and includes a ValidationAttribute class that acts as the base class for validation attributes. An example of a validation attribute is Required, which is used to indicate that a property is a required value.

DataAnnotations are available in both .NET and Silverlight, though it turns out that their implementations aren’t quite the same. Still, their usage is the same, in that you decorate properties with data annotation attributes.

The idea behind DataAnnotations is that they are UI independent. If you put a Required attribute on a property, and then you build a UI using a technology that understands these ValidationAttribute subclasses, the UI will honor the attribute. The Silverlight DataForm is one example of a UI technology that does understand these attributes, and I suspect we’ll see many more UI technologies start to leverage them.

What’s interesting about this, is that the attribute object itself contains the validation rule logic. So the UI doesn’t actually implement the Required rule logic – it just asks the attribute object to do the evaluation. This is where things aren’t the same on .NET and Silverlight. On .NET ValidationAttribute subclasses override IsValid(), returning true if the rule is satisfied, false if not. On Silverlight ValidationAttribute subclasses override GetValidationResult() which returns null if the rule is satisfied, and a result object if the rule is broken. Either way the basic concept is the same, but the implementation code is different.

I wanted to support these attributes in CSLA .NET (for Windows and Silverlight). This is really a two-part process.

First, I needed to have a way to detect the attribute on a property, and attach a CSLA validation rule to that property so CSLA knows to execute the attribute’s rule when appropriate. CSLA .NET already has a business/validation rule subsystem that knows how to execute rules – I just needed to auto-add rules for data annotation attributes.

Second, I needed a way to execute any ValidationAttribute subclass, since that’s how one of these rules is evaluated. Again, CSLA .NET already has a validation rule subsystem that says validation rules are methods. So I just needed to create a CSLA-style rule method that knows how to invoke a ValidationAttribute to actually evaluate the rule’s condition.

I added a ValidationRules.AddDataAnnotations() method that you can call in your AddBusinessRules() override. This method reflects against your properties, detects any ValidationAttribute subclasses on any of your properties and adds a CSLA-style rule to link that property to the rule attribute. I also changed BusinessBase.AddBusinessRules() (this is the base method) so AddDataAnnotations() is called if you don’t override AddBusinessRules() – effectively making the use of data annotation attributes a default behavior.

Then I created a Csla.Validation.CommonRules.DataAnnotation() rule method. This is the rule method that is automatically associated with properties by AddDataAnnotations(). The DataAnnotation() rule method is pretty simple – it just executes the attribute object’s IsValid() or GetValidationResults() methods (depending on whether the code is running on .NET or Silverlight).

The end result is that when using CSLA .NET 3.8 you can apply data annotation attributes to your business class properties, and (assuming AddDataAnnotations() is called) they’ll be automatically linked into the normal CSLA .NET validation subsystem and executed like any other CSLA .NET business or validation rules.

[Serializable]
public class Data : BusinessBase<Data>
{
  private static PropertyInfo<int> IdProperty = 
    RegisterProperty<int>(c => c.Id);
  [Range(0, 10, ErrorMessage = "Id must be between 0 and 10")]
  public int Id
  {
    get { return GetProperty(IdProperty); }
    set { SetProperty(IdProperty, value); }
  }

  private static PropertyInfo<string> NameProperty =
    RegisterProperty<string>(c => c.Name);
  [Required(ErrorMessage = "Name is required")]
  public string Name
  {
    get { return GetProperty(NameProperty); }
    set { SetProperty(NameProperty, value); }
  }
}

Notice that this class doesn’t override AddBusinessRules(), so the base implementation is used, and the base implementation calls ValidationRules.AddDataAnnotations().

When AddDataAnnotations() is called, it detects the Range and Required attributes on the properties, and those attributes are automatically linked into the normal CSLA .NET business rule subsystem. This means the rules are automatically checked when a new instance of the object is created, and any time the property values are set – exactly the behavior you’d get with regular CSLA .NET rule methods.

But what’s nice about this is that these attributes are also honored by some UI technologies (like DataForm). This means that you automatically get the UI behaviors (if any) and yet you know that the rules will be run in the business layer regardless of whether the UI honors the attributes or not.

So this object will work nicely in the Silverlight DataForm, and will have the same business behavior in Windows Forms, behind a WCF service or anywhere else the object is used – even if the UI technology doesn’t honor the attributes.

You can also use this approach to create your own validation attributes by subclassing the ValidationAttribute base class in System.ComponentModel.DataAnnotations.

The only limitation I’ve found is that these attribute-based rules can only operate on a single property value. You can’t use this technique to do multi-property rules, or rules that operate on child collections or across other objects. You’ll need to use the normal CSLA .NET business/validation rule method approach to implement anything beyond simple single-property rules.

Monday, October 5, 2009 11:06:45 AM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Saturday, October 3, 2009

CSLA .NET version 3.8 Beta 1 is now available for download.

Beta 1 brings the WPF PropertyStatus in line with the Silverlight version.

And Beta 1 adds support for the System.ComponentModel.DataAnnotations attributes. Data annotation attributes applied to properties are automatically added as rules using the CSLA .NET validation rules subsystem when ValidationRules.AddAnnotations() is called in your AddBusinessRules() override. If you don’t override AddBusinessRules() the base implementation calls AddAnnotations() on your behalf.

The C# ProjectTracker has been updated to work with 3.8.

Saturday, October 3, 2009 10:07:14 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Tuesday, September 29, 2009

CSLA .NET version 3.8.0 alpha 3 is now available.

The primary focus of version 3.8 is to enable more seamless support for the MVVM design pattern in Silverlight and WPF. The alpha 3 release brings the features I’ve been implementing in Silverlight into WPF.

Also, the samples downloads now include my MVVM experimental applications. I suppose you can call these samples, but they are really the apps I’m using to try out different ideas – so they aren’t what I’d consider a “full sample”. Still, you can see how the various new features work, and how the MVVM features allow creation of at least a basic CRUD UI (with some navigation) with no code-behind any XAML.

Please note that version 3.8 requires System.Windows.Interactivity.dll to build. This assembly is installed with Expression Blend 3, or the Blend 3 SDK. You must install at least the SDK before you can build CSLA .NET 3.8.0.

The new features (now in Silverlight and WPF) include:

  • New ViewModelBase and ViewModel base classes to simplify the creation of view model types in your application. ViewModelBase provides protected methods to simplify interaction with business object types, and ViewModel is an example subclass that exposes public methods for use by InvokeMethod or Execute
  • CslaDataProvider enhancements to allow “chaining” of data providers (so a child data provider’s ObjectInstance property can be bound to a property from a parent data provider’s business object)
  • InvokeMethod enhancements to handle essentially any UI control event, and to invoke either data provider or view model methods, including passing parameter values from data bound sources in the UI. Additionally, InvokeMethod is now fully bindable which simplifies (but changes) the XAML needed to use the control
  • Execute trigger action, which is somewhat like InvokeMethod, but is an action used within a System.Windows.Interactivity trigger handler. The trigger action model imposes some limitations on data binding, so Execute isn’t quite as powerful as InvokeMethod, but it is more compatible with the Blend 3 designer model
  • PropertyStatus enhancements so you can bind your UI control’s properties to properties on PropertyStatus to control its visual state. This is instead of having PropertyStatus try to directly manipulate the visual state of the UI control. Additionally, PropertyStatus is now fully bindable which simplifies (but changes) the XAML needed to use the control
  • MobileFormatter now uses binary XML by default to help improve performance

Please give these new features a try and let me know your thoughts on the forum.

Tuesday, September 29, 2009 2:36:13 PM (Central Standard Time, UTC-06:00)  #    Disclaimer

Thanks to a tremendous amount of time and effort on the part of Sean Rhone there’s a new release of CSLA .NET VB available for download from the VB download page.

Thank you Sean!!

This VB version of the framework should now have full parity with CSLA .NET for Windows 3.6.3. There’s one slight difference with the async data portal to work around the lack of multi-line lambda expressions in VB 9 – hopefully we’ll be able to bring that code back into parity with C# when VB 10 is available.

I recommend using this VB version of the framework as an implementation reference, not for production. The official release of CSLA .NET for Windows is the C# implementation, which is currently at version 3.7.1. It is available from the download page.

Tuesday, September 29, 2009 12:32:15 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Monday, September 28, 2009

CSLA .NET 3.7.1 for Windows and Silverlight are now available for download.csla_logo1_32_r

Version 3.7.1 supports .NET 3.5 SP1 and Silverlight 3.

This is primarily a bug fix release to address some issues with 3.7.0. Please see the change logs for details about the changes.

If you are using CSLA .NET version 3.5 or higher I recommend you look at the 3.7.1 release, as this is the current version for use with .NET 3.5 SP1, Visual Studio 2008 and Silverlight 3.

Monday, September 28, 2009 1:04:14 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Sunday, September 13, 2009

I have put two new pre-releases online, and they are available on the download pages:

CSLA .NET 3.7.1 Beta 3 is near-stable. In fact it would have been a release, except for one change I just added that I feel needs a beta cycle.

The 3.7.1 release is primarily bug fixes for a few issues in 3.7.0.

The only new feature is some support for creating custom FieldInfo<T> subclasses, which requires creating PropertyInfo<T> subclasses. If you are doing this, the new 3.7.1 changes in Beta 3 may make your life much easier.

CSLA .NET 3.8.0 Alpha 2 shows my continuing work and thoughts around the new Silverlight 3 binding capabilties and MVVM support.

All the new changes in Alpha 2 are on the Silverlight side, and impact:

  • CslaDataProvider - where the ObjectInstance property is now bindable, so you can "chain" data provider controls in parent-child relationships. This means you can have a child region on a form that is bound to a CslaDataProvider that got its data from the child property of a parent CslaDataProvider.
  • ViewModelBase - a base class that provides protected members you can use to more easily create a ViewModel class for your CSLA .NET business objects. The approach taken is one that exposes the Model (your business object) as a Model property of the ViewModel object; this is the flavor of MVVM that works best with CSLA .NET.
    This does include a protected method to create/fetch the Model as requested in one of the recent MVVM threads on the CSLA .NET forum.
  • ViewModel - a subclass of ViewModelBase that exposes public members for use with InvokeMethod or Execute (see below) so the methods can be invoked directly by XAML. Warning: I may or may not keep this class, depending on your feedback, as I don't know if it is the best plan overall.
  • InvokeMethod - which has breaking changes, but now automatically binds to the current DataContext and does a whole bunch of other nice work on your behalf to invoke methods on a data provider or ViewModel.
  • Execute - a new event trigger action using the new Blend 3 SDK feature of event triggers. The Execute action is similar to InvokeMethod, but works within the new event trigger infrastructure.
  • PropertyStatus - which has breaking changes, and is now bindable using element binding, and binds to the business object property instead of using a string literal for the property name. It also now exposes properties so a UI control can bind to PropertyStatus, instead of having PropertyStatus directly alter the UI control - this offers major new flexibility in UI design.

If you are using SL3 and/or are at all interested in MVVM, please take a look at what I'm doing in 3.8 and provide feedback.

As always, my intent is not for CSLA .NET to become a UI framework. At the same time, I feel the need to fill in at least the most glaring holes in the UI layer to enable use of CSLA .NET - and this means providing a basic way for XAML to invoke ViewModel methods, and for validation/authorization rules to be expressed in a rich manner in the UI.

It should be the case that any MVVM UI framework will be compatible with viewmodel objects you create by subclassing ViewModelBase. If that's not true, I'd like to hear about the issues you run into. Since ViewModelBase exposes nearly all protected members (except for Model, IsBusy and Error, which are public), I expect that it will provide an incredibly flexible start point for creating viewmodel objects.

The ViewModel base class is an example of how ViewModelBase can be subclasses to create a base that works with a specific UI implementation - specifically InvokeMethod and/or Execute.

Assuming generally positive feedback on the changes I've made on the Silverlight side, I'll port the appropriate changes to the WPF side, and then release 3.8.

Sunday, September 13, 2009 11:22:15 AM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Wednesday, September 2, 2009

I keep plucking away at the MVVM ideas, trying to make sure CSLA .NET allows people to implement the pattern in a smooth manner.

But I keep fighting with UI stuff in the process…

My scenarios center around the ListBox, because I find it to be nicely problematic. And common. Most apps have lists of stuff, and users select n items from the list and then do something with the items. So single-select and multi-select ListBox scenarios, where actions are triggered by the selection changing, or when a button is clicked – this is my current problem domain. Pure UI stuff.

I updated my existing InvokeMethod component to solve these problems, with some challenges, but it works nicely to invoke a method on a ViewModel. I’ve also played with the EventTrigger concepts from Blend 3, creating an Execute trigger action that invokes a method on the ViewModel, but there are some serious limitations here.

One scenario is pretty easy – triggering an action from the SelectionChanged event of the ListBox itself. The InvokeMethod and Execute solutions can both be handled with zero code-behind – just XAML interacting with the ViewModel.

Single-select with InvokeMethod

With InvokeMethod it looks like this:

<ListBox ItemsSource="{Binding Path=Model}"
         ItemTemplate="{StaticResource DataList}"
         Name="DataListBox"
         csla:InvokeMethod.Target="{Binding Source={StaticResource ListModel}}"
         csla:InvokeMethod.TriggerEvent="SelectionChanged"
         csla:InvokeMethod.MethodName="ShowItem"
         csla:InvokeMethod.MethodParameter="{Binding RelativeSource={RelativeSource Self}, Path=SelectedItem}" />

And the ViewModel has a ShowItem() method like this:

public void ShowItem(Data methodParameter)
{
  // process methodParameter
}

Very simple and easy, and I like it a lot – except that InvokeMethod is fairly verbose and isn’t supported by Blend. I do like that the selected item is passed into the method as a strongly typed parameter though.

Single-select with event trigger

Using the event trigger model (which is supported by Blend) the ListBox looks like this:

<ListBox ItemsSource="{Binding Path=Model}"
         ItemTemplate="{StaticResource DataList}"
         SelectedItem="{Binding Path=SelectedData, Mode=TwoWay}"
         Name="DataListBox">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectionChanged">
      <csla:Execute MethodName="ShowItem2" />
    </i:EventTrigger>
  </i:Interaction.Triggers>
</ListBox>

Notice that the ListBox.SelectedItem property is now bound to the SelectedData ViewModel property:

public static readonly DependencyProperty SelectedDataProperty =
    DependencyProperty.Register("SelectedData", typeof(Data), typeof(DataListViewModel), new PropertyMetadata(null));
public Data SelectedData
{
  get { return (Data)GetValue(SelectedDataProperty); }
  set { SetValue(SelectedDataProperty, value); OnPropertyChanged("SelectedData"); }
}

And the ViewModel method looks like this:

public void ShowItem2(object sender, Csla.Silverlight.ExecuteEventArgs e)
{
  // process this.SelectedData
}

While this is supported by Blend, I dislike the fact that the command method (ShowItem2()) has an invisible side-effect in that it requires the SelectedData property to be set before it will work. No one could know this without looking at the code or at documentation, so the overall readability is reduced in my opinion.

However, both solutions end up with a ShowItem() method that has the strongly-typed selected item, and the XAML uses binding to interact with the ViewModel in a reasonably clean manner – so I think either way is perfectly acceptable.

Multi-select with InvokeMethod

The multi-select ListBox scenario requires a Button (or similar control). The user selects multiple items in the ListBox, then clicks the Button to trigger processing of those items.

This scenario is not nearly so nice. Partly this is because of the way the ListBox works I think (or binding). The problem is that the SelectedItems property of the ListBox returns an ObservableCollection<object>, and when a binding is established between SelectedItems and another property it gets a reference to a collection that is not the collection you ultimately want.

In other words, when the form loads, SelectedItems points to an empty collection, and anything bound to it gets connected to that collection. When items are later selected the SelectedItems property seems to end up pointing to a different collection, and the binding has no idea this happened. The binding is still pointing to the original empty collection.

This means the binding to SelectedItems must be refreshed at the time the event trigger occurs, such as the Button control’s Click event.

I made InvokeMethod take care of this, so when using InvokeMethod the ListBox looks like this:

<ListBox ItemsSource="{Binding Path=Model}"
         ItemTemplate="{StaticResource DataList}"
         SelectionMode="Multiple"
         Name="DataListBox" />

And the Button looks like this:

<Button Content="Process items"
        csla:InvokeMethod.TriggerEvent="Click"
        csla:InvokeMethod.MethodName="ProcessItems"
        csla:InvokeMethod.MethodParameter="{Binding ElementName=DataListBox, Path=SelectedItems}"/>

And the ViewModel method looks like this:

public void ProcessItems(System.Collections.ObjectModel.ObservableCollection<object> methodParameter)
{
  // process methodParameter
}

This only works because InvokeMethod refreshes the binding of its MethodParameter property when it gets the Click event from the Button. If it just took the normal binding value, it would always return an empty collection…

But the fact is that InvokeMethod does make this work in a very smooth and easy manner, allowing the ViewModel to implement a method that accepts the list of selected items as a parameter.

Multi-select with event trigger

Using the trigger action approach things are really messy, because there’s no way to force a refresh of anything that is bound to SelectedItems.

Worse, you can’t actually bind SelectedItems on the ListBox itself like you bind SelectedItem. In other words, the ListBox ends up looking like this:

<ListBox ItemsSource="{Binding Path=Model}"
         ItemTemplate="{StaticResource DataList}"
         SelectionMode="Multiple"
         Name="DataListBox">
</ListBox>

Where you’d want to bind SelectedItems to a property of the ViewModel, that’s not possible.

So I thought I’d use a bit of a hack and bind it to the Tag property of the Button:

<Button Content="Process items"
        Tag="{Binding ElementName=DataListBox, Path=SelectedItems}">
  <i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
      <csla:Execute MethodName="ProcessItems2" />
    </i:EventTrigger>
  </i:Interaction.Triggers>
</Button>

While this “works”, it doesn’t really. The problem is that the binding is established when SelectedItems is an empty collection, and it never changes. So this is NOT a useful way to get the list of selected items.

In the end, the solution appears to be that the ViewModel must know that it is dealing with a ListBox so it can get the items directly in the command method. That means the Button must provide a link to the ListBox (via Tag):

<Button Content="Process items"
        Tag="{Binding ElementName=DataListBox}">

This way the command method can interact with the Tag property to get a reference to the ListBox to get at the SelectedItems collection:

public void ProcessItems2(object sender, Csla.Silverlight.ExecuteEventArgs e)
{
  var listBox = ((System.Windows.Controls.Control)e.TriggerSource).Tag as System.Windows.Controls.ListBox;
  var selection = listBox.SelectedItems;
  // process selection
}

This is bad because now the ViewModel must know details about the control in the View. It is directly using the ListBox type, which means that the XAML can’t be easily changed to use some other type of list-oriented UI control – at least not without coming back here and changing this code.

I guess one solution would be to create a custom Button subclass that refreshes the binding of its Tag property when the button is clicked – but that’s not a good general solution by any means…

So in the multi-select scenario InvokeMethod is a decent solution, but trigger actions really fall down and the solution seems very inadequate. I think this is primarily due to the implementation of ListBox.SelectedItems, but I also think it is safe to assume that other UI controls will have similarly ill-behaved properties that make trigger actions harder to use than they should be.

Wednesday, September 2, 2009 3:25:26 PM (Central Standard Time, UTC-06:00)  #    Disclaimer