Silverlight w/MVVM Pattern – Asynchronous Binding when loading a new view

I’ve been struggling on a part of the MVVM pattern implementation : basically ‘how do I update the view on the view’s load to bind to a control (like a list).  This is common senario where you are fetching data for the display.

Basically the binding seems to occur when the page is loaded and when the asynchronous call returns I’ve been unable to get the UI element to pick up the updated list (ie. observable list).  I don’t want to have any code in my view code behind, I’m 99% there…

After much trying and experimentation I found this article with sample code.

I’m going to take this sample, and build on it.. try it out on my sample test application…. keep your fingers crossed  :)  I’ll write back on the steps needed to do it… if it works!

UPDATE:  works perfectly.  This sample shows off a few other key items: 

  1. Dependency Injection + ServiceLocator 
  2. Commanding (SLExtensions) – basic commanding – I would like to use the Caliburn commanding, simply because I like that it handles just about any event… that will be my next stop.

UPDATE 2: the problem I described, I was able to figure it out when using Caliburn.

When the asynchronous call is completed it’s important to:

Previously I was doing this:

public void CompanyLoadingComplete(object sender, Model.EventArguments.CompanyLoadedEventArgs e)
        {
            CompanyList = e.Results;
        }

Then I tried this instead:

public void CompanyLoadingComplete(object sender, Model.EventArguments.CompanyLoadedEventArgs e)
        {
            CompanyList.Clear();
            foreach(var result in e.Results)
            {
                CompanyList.Add(result);
            }
        }

Silverlight: Getting around the ‘z-index problem’

Figured I’d pass this around if someone searches on it:

basically if you have elements on the page that use z-index, ie. I have a yahoo menu that has dropdown selections. By default the menu items are obscured by the silverlight control.

To fix this problem, you can set parameters on the silverlight object/control:

<param name="windowless" value="true" />

You can also set other properties like transparent background:

<param name="background" value="transparent" />

(Edited for comment below)

ie.

image

Silverlight: Getting around the ‘z-index problem’

Figured I’d pass this around if someone searches on it:

basically if you have elements on the page that use z-index, ie. I have a yahoo menu that has dropdown selections.  By default the menu items are obscured by the silverlight control.

To fix this problem, you can set parameters on the silverlight object/control:

<param name="windowless" value="true" />

You can also set other properties like ‘transparent background’:

<param name="background" value="transparent" />

(Edited for comment below)

ie.

image

Silverlight MVVM Problem…Question

Well, I’m struggling with a few items with Silverlight, MVVM and databinding.

After reading this good article here on msdn http://msdn.microsoft.com/en-us/magazine/dd458800.aspx

I ran through the sample, looks pretty good, etc…

Few problems though…

1. the ViewModel constructor.  If I use this, I can’t use Blend any longer.  I get a memory corruption message.  I tried it on 2 different projects, same issue.  Not sure what is behind it

public GamesViewModel() :
      this(new GameCatalog())
    {
    }

    public GamesViewModel(IGameCatalog catalog)
    {
      theCatalog = catalog;
      theCatalog.GameLoadingComplete +=
        new EventHandler<GameLoadingEventArgs>(games_GameLoadingComplete);
      theCatalog.GameLoadingError +=
        new EventHandler<GameCatalogErrorEventArgs>(games_GameLoadingError);
    }

2. In my sample, similiar to this one in the article… my ‘Games’ returned are in the thousands – ie. 3000 records.   I only want to show the top 50.   I’ve been unable to get this work and resorted to manually coding up the binding in the code behind of the view – something of course I’m trying to avoid with this model.

ie. here is my viewModel:

 

public ServicesView()
        {
            InitializeComponent();
            Loaded += OnPageLoaded;

            viewModel = Resources["ServicesViewModel"] as ServicesViewModel;
            if (viewModel != null)
            {
                viewModel.LoadComplete += viewModelLoadComplete;
                viewModel.GetServices();
            }
        }

void viewModelLoadComplete(object sender, EventArgs e)
        {
            FilterCriteria.ItemsSource = viewModel.FilteredServiceList;
            ServiceListBox.ItemsSource = viewModel.FilterByCriteria(string.Empty);
            ProgressIndicator.IsActive = false;
            ServiceContent.Visibility = Visibility.Visible;
        }

The two bolded lines…I want to bind using the XAML, but it’s not taking.  Seems to me it’s related to the order in which things are occuring.

ie. here is the main list coming back from the database:

public ObservableCollection<ServiceClient> ServiceClients
        {
            get
            {
                return serviceClients;
            }
        }

That list receives 3000 service clients on load complete.

The ServiceListBox is bound in xaml, this will work, but gets 3000+

<ListBox x:Name="ServiceListBox" Height="320" Width="448" HorizontalAlignment="Left" VerticalAlignment="Bottom" 
                     Grid.Row="1"
                     Grid.ColumnSpan="2"
                     Style="{StaticResource ListBoxStyle}"
                     ItemsSource="{Binding ServiceClients, Source={StaticResource ServicesViewModel}}"
                     ItemTemplate="{StaticResource ServiceClientsTemplate}" Margin="32,0,0,36" d:UseSampleData="True"/>

So, what I tried to do was filter it out:

ViewModel:

ie.

public List<ServiceClient> FilteredServiceClient
        {
            get
            {
                return ServiceClients.OrderBy(c => c.ServiceDescription).Take(50).ToList();
            }
        }

<ListBox x:Name="ServiceListBox" Height="320" Width="448" HorizontalAlignment="Left" VerticalAlignment="Bottom" 
                     Grid.Row="1"
                     Grid.ColumnSpan="2"
                     Style="{StaticResource ListBoxStyle}"
                     ItemsSource="{Binding FilteredServiceClient, Source={StaticResource ServicesViewModel}}"
                     ItemTemplate="{StaticResource ServiceClientsTemplate}" Margin="32,0,0,36" d:UseSampleData="True"/>

However, this data is never bound to the list… (and I’ve tried making this list an observablecollection, same problem)

Silverlight MVVM Problem…Question

Well, I’m struggling with a few items with Silverlight, MVVM and databinding.

After reading this good article here on msdn http://msdn.microsoft.com/en-us/magazine/dd458800.aspx

I ran through the sample, looks pretty good, etc…

Few problems though…

1. the ViewModel constructor.  If I use this, I can’t use Blend any longer.  I get a memory corruption message.  I tried it on 2 different projects, same issue.  Not sure what is behind it

public GamesViewModel() :
      this(new GameCatalog())
    {
    }

    public GamesViewModel(IGameCatalog catalog)
    {
      theCatalog = catalog;
      theCatalog.GameLoadingComplete +=
        new EventHandler<GameLoadingEventArgs>(games_GameLoadingComplete);
      theCatalog.GameLoadingError +=
        new EventHandler<GameCatalogErrorEventArgs>(games_GameLoadingError);
    }

2. In my sample, similiar to this one in the article… my ‘Games’ returned are in the thousands – ie. 3000 records.   I only want to show the top 50.   I’ve been unable to get this work and resorted to manually coding up the binding in the code behind of the view – something of course I’m trying to avoid with this model.

ie. here is my viewModel:

 

public ServicesView()
        {
            InitializeComponent();
            Loaded += OnPageLoaded;

            viewModel = Resources["ServicesViewModel"] as ServicesViewModel;
            if (viewModel != null)
            {
                viewModel.LoadComplete += viewModelLoadComplete;
                viewModel.GetServices();
            }
        }

void viewModelLoadComplete(object sender, EventArgs e)
        {
            FilterCriteria.ItemsSource = viewModel.FilteredServiceList;
            ServiceListBox.ItemsSource = viewModel.FilterByCriteria(string.Empty);
            ProgressIndicator.IsActive = false;
            ServiceContent.Visibility = Visibility.Visible;
        }

The two bolded lines…I want to bind using the XAML, but it’s not taking.  Seems to me it’s related to the order in which things are occuring.

ie. here is the main list coming back from the database:

public ObservableCollection<ServiceClient> ServiceClients
        {
            get
            {
                return serviceClients;
            }
        }

That list receives 3000 service clients on load complete.

The ServiceListBox is bound in xaml, this will work, but gets 3000+

<ListBox x:Name="ServiceListBox" Height="320" Width="448" HorizontalAlignment="Left" VerticalAlignment="Bottom" 
                     Grid.Row="1"
                     Grid.ColumnSpan="2"
                     Style="{StaticResource ListBoxStyle}"
                     ItemsSource="{Binding ServiceClients, Source={StaticResource ServicesViewModel}}"
                     ItemTemplate="{StaticResource ServiceClientsTemplate}" Margin="32,0,0,36" d:UseSampleData="True"/>

So, what I tried to do was filter it out:

ViewModel:

ie.

public List<ServiceClient> FilteredServiceClient
        {
            get
            {
                return ServiceClients.OrderBy(c => c.ServiceDescription).Take(50).ToList();
            }
        }

<ListBox x:Name="ServiceListBox" Height="320" Width="448" HorizontalAlignment="Left" VerticalAlignment="Bottom" 
                     Grid.Row="1"
                     Grid.ColumnSpan="2"
                     Style="{StaticResource ListBoxStyle}"
                     ItemsSource="{Binding FilteredServiceClient, Source={StaticResource ServicesViewModel}}"
                     ItemTemplate="{StaticResource ServiceClientsTemplate}" Margin="32,0,0,36" d:UseSampleData="True"/>

However, this data is never bound to the list… (and I’ve tried making this list an observablecollection, same problem)

Silverlight – XAML – Visual Studio 2008 Crashes

 

Update 4: http://www.lhotka.net/weblog/WorkingWithWPFOrSilverlightYouNeedThisPatch.aspx

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

Well… there are others that get this* , and it’s very irritating.

Basically if I leave a ‘xaml’ page open and hit debug, Visual Studio crashes to desktop.  So, before I hit debug, I must close the xaml.

I have errors in my Application log in event viewer:

.NET Runtime version 2.0.50727.3053 – Fatal Execution Engine Error

 

Very irritating to say the least…

The silverlight tools imo are very buggy, so we can hope as the product matures it gets better.  Silverlight is still sweet, just ‘young’ – in it’s infancy still – I think whatever Silverlight 1.0 was… well, Silverlight 2.0 feels like a beta to me.

I still like it though  🙂

 

* I’ve search around, I see others getting this problem too, but no real solutions available.  One guy said he uninstalled .net 3.5 sp1 and it stopped, but that isn’t an option for me…

UPDATE: seems to only happen for me right now when I’m using asp.net mvc project in my solution with the Silverlight

UPDATE 2 : Actually I realized that only my asp.net mvc projects were using AnknSVN.  After uninstalling AnknSVN I haven’t had any crashes… yet….  :)   I like AnknSVN so I will look into submitting a bug – however, I’ll have to uninstall it for now

UPDATE 3: (I reinstalled AnknSVN problem solved …. so far)

Here is possible fix: http://blogs.msdn.com/webdevtools/archive/2009/03/03/hotfix-available-for-asp-net-mvc-crashes-with-azure-power-commands-resharper.aspx