views:

1083

answers:

1

As part of learning WPF I just finished working through an MS Lab Exercise called "Using Data Binding in WPF" (http://windowsclient.net/downloads/folders/hands-on-labs/entry3729.aspx).

To illustrate using an IMultiValueConverter, there is a pre-coded implementation of one where the boolean result is used to determine whether the data binding is relevant for the current user. Here is the code for the convert operation:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        // var rating = int.Parse(values[0].ToString());
        var rating = (int)(values[0]);
        var date = (DateTime)(values[1]);

        // if the user has a good rating (10+) and has been a member for more than a year, special features are available
        return _hasGoodRating(rating) && _isLongTimeMember(date);
    }

And here is the wiring to use this in the XAML:

<ComboBox.IsEnabled>
    <MultiBinding Converter="{StaticResource specialFeaturesConverter}">
    <Binding Path="CurrentUser.Rating" Source="{x:Static Application.Current}"/>
    <Binding Path="CurrentUser.MemberSince" Source="{x:Static Application.Current}"/>
    </MultiBinding>
</ComboBox.IsEnabled>

The code runs fine, but the XAML designer will not load with a "Specified cast not valid." error. I tried a couple of ways to not use a cast, one of which I left uncommented in the code above. The funny thing is a finished lab exercise provided by MS also has the error.

Does anyone know how to fix it to make the designer happy?

Cheers,
Berryl

+4  A: 

Hey Berryl,

Problem here is that you use Application.Current, which is different in Design mode and in runtime.

When you open designer, Application.Current will not be your "App" class (or whatever you name it). Thus there are no CurrentUser property there, and your get that error.

There are multiple ways to fix it. The easiest one is to check if you are in design mode:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
  if (Application.Current == null ||
      Application.Current.GetType() != typeof(App))
  {
    // We are in design mode, provide some dummy data
    return false;
  }

  var rating = (int)(values[0]);
  var date = (DateTime)(values[1]);

  // if the user has a good rating (10+) and has been a member for more than a year, special features are available
  return _hasGoodRating(rating) && _isLongTimeMember(date);
}

Another approach would be not using Application.Current as a source for your binding.

Hope this helps :).

Anvaka
Spot on. Makes one wonder why the good folks at MS couldn't bother to explain this as well as you just did when they publish *learning* material! Cheers
Berryl