RSS
 

Archive for the ‘Silverlight’ Category

Silverlight Unit Testing: Howto

12 Aug

This post will walk you through setting up a Unit Test Project for your Silverlight Application. It took me a day to successfully set everything up and make it working on a Team Foundation Build Server. The Silverlight Unit Test Framework is already out some years (starting from Silverlight 2) but with every new framework it is good to wait for some maturity. I will blog about the Unit Testing framework as it is now in Silverlight 4.

Prerequisites:

Setup your Unit Test Silverlight Application

After installing the Silverlight Toolkit, you should have a Silverlight Unit Test Project available. The following screens will walk you through the setup.

 

    

 

Unit Testing your XAML Bindings

As we all use MVVM in our Silverlight applications these days… Make sure it doesn’t break any of the bindings.

Reasons that I could think of to test your XAML bindings.

  • Typographical error in your XAML
  • Make sure you don’t miss the silent tracing error of your binding mistake
  • Your object property name changes
  • Designers might mess with your bindings

 

First approach (howto test XAML bindings??)

There is a post by Jeremy Likeness that deals with testing your XAML bindings. The post was quite good and you get the idea but the code didn’t work very well for me.

Second and working approach.

The following code works for me and has a completely different approach. Silverlight Unit Testing has a number of methods to support the behaviour we are trying to test.

        [Asynchronous]
        [TestMethod]
        [Tag("WorkflowDefinitionBindingIsValid")]
        public void WorkflowDefinitionBindingIsValid()
        {
            EnqueueDelay(10);

            // Internal Property Available using Assembly InternalsVisibleTo on Silverlight Project
            var cbBooksCombobox = _booksView.cbBooksCombobox;

            EnqueueCallback(() => { _booksViewModel.Books = _books; });
            EnqueueCallback(() => CollectionAssert.AreEquivalent(cbBooksCombobox.Items, _books,
                                                    "Failed to data-bind books."));

            EnqueueTestComplete();
        }

Explanation:

  • The Asynchronous Attribute is very important for these kind of tests. We want to allow the bindings to update before we continue further test execution.

 

  • Enqueue methods
    • EnqueueTestComplete() – This method indicates that your test is complete.
    • EnqueueCallback() – This method will add a callback to your test method.
    • EnqueueConditional() – Continue testing after the condition is met.
    • EnqueueDelay() – Add a delay before continuing to evaluate work items.
    • EnqueueWorkItem – This adds a task to the task queue.

 

  • Getting access to the internal properties of your viewModel
        [assembly: InternalsVisibleTo("org.vanderbiest.UnitTests")]

 

  • Tagging your tests

You can tag your class and also tag your methods. I find it handy to tag both so you can test individual methods or just test your entire fixture class.

As you can see in the Sample Screenshot, I have placed my own Favorite Tags in the list. To achieve that, you will add the following code to the App.xaml.cs Startup event.

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            var settings = UnitTestSystem.CreateDefaultSettings();
            settings.SampleTags.Clear();
            settings.SampleTags.Add("BaseViewModelFixture");
            settings.SampleTags.Add("BookListViewModelFixture");
            settings.SampleTags.Add("MusicListViewModelFixture");
            RootVisual = UnitTestSystem.CreateTestPage(settings);
        }

 

Third approach: EnqueueConditional method

You might also want to check the following approach:

[TimeOut(200)]
[TestMethod]
[Asynchronous]
public void Test2()
{
int pageCount = 0;
FlickrRequest request = new FlickrRequest(typeof(MockTestableWebClient));
request.PhotoSearchByUser("97044050@N00", (photo) => pageCount++);
EnqueueConditional(() =>
{
return pageCount == 5;
});
EnqueueTestComplete();
}

This code will wait for a certain condition to be completed. Notice the TimeOut attribute to make sure you don’t fall into an endless loop…

The EnqueueCondition becomes handy when you want to test real time WCF calls.

Automating your Silveright Unit Tests at Build Server

StatLight

Differences in StatLight Visual Studio Debug - No Error Logging in TestInitialize

If something goes wrong in your Test Initialization you won’t get a good error description in StatLight. This is because of the Silverlight Test Framework not throwing any exceptions in your Test Initialization. Of course we don’t have any problems with it as long as we can debug our code but with StatLight, things are a bit different. It is recommended that you have a Smoke test that just checks your Initialization method for errors.

        [TestInitialize]
        public void TestInit()
        {
            // Nothing goes wrong here as we can see in our smoke test
        }

        [TestMethod]
        [Description("Tests the InitializeMethod")]
        [Tag("SmokeTest")]
        public void SmokeTest()
        {
            TestInit();
        }

Caveat?

Resources are not automatically recognized by Statlight. You need to add them manually. What resources you need to add manually can be discovered by using the smoke test. To add a resource manually, you need to add the following code:

        public static void Get()
        {
            Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary
            {
                Source =
                    new Uri(
                    "/org.vanderbiest.Shell;component/Assets/Styles/BaseStyle.xaml",
                    UriKind.RelativeOrAbsolute)
            });
        }

Testing UIElements requires the -b option.

When you run your Silverlight Unit Tests in Visual Studio, the browser will load the XAP file and launch all the tests. The default with StatLight is that it runs without a browser. Luckily for us we can test our XAML bindings using the -b option. Statlight has its own browser process window so that tests will run in a browser context.

 

Reporting using StatLight

StatLight.exe -x=MyTestXapFile.xap -b -ReportOutputFile=C:\temp\test.xml



  
    
      
        Description
      
    
    
   

Why? StatLight is a commandline utility that will execute your tests in an automated environment.
Reports.

Howto?

  • You can install StatLight as a NuGet Package.

 

 

Visual Studio Silverlight Unit Test Result Viewers

Usage? Instead of running in a browser window or launch a command line process, directly view your Unit Test Results in Visual Studio.

AgUnit

Installation

Download: AgUnit on CodePlex

Copy the extracted files from AgUnit-0.4-for-ReSharper-6.0.zip into the “Bin\Plugins\” folder of your ReSharper installation
(default C:\Program Files\JetBrains\ReSharper\v6.0\Bin\Plugins), create this folder if it does not exist. Delete any previous versions of AgUnit you may have in this folder.

Caveat

As you will see with XAML binding tests… Async is currently not working

 

Unit Test Result Viewer for StatLight

Download from Visual Studio Gallery

Overall, the plugin did not help me at all. I experienced the following problems:

  • Test Project should not be located in a Solution Folder (the assembly will not be recognized by the Result Viewer Tool)
  • I could not make it work (after placing StatLight in my Appdata/Local directory), I must did something wrong ;)

 

Conclusion

There are still some Caveats and there isn’t very much documentation on the net but you can make it work as I described in this blog post.

 

 

Animate your Silverlight ItemsControl

17 Oct

The idea behind the animation is to inform the users of the new items that were added to the ItemsControl. The new items will fly into the screen from left and right.

Let’s take an existing example from here by Tim Heuer:
Twitter Search Monitor

The ItemsControl in the example consists of a DataTemplate defined in a resource.

Let’s check the following original code snippet from Search.xaml:

            
                
            

If we examine the ItemsControl, we can see that it has a reference to a SearchResultsTemplate Resource. This DataTemplate Resource is defined in the SearchPage. To interact with the items, we need to copy this DataTemplate to a new UserControl.

Now we want to change the reference to the DataTemplate in the Page.Resources to our own UserControl (TwitterItem) in Search.xaml:

 
                
                    
                        
                            
                        
                    
                    
                        
                            
                            
                            
                            
                        
                    
                
            

We can now add some Storyboards to our TwitterItem.xaml:

	

			
				
					
						
					
				
				
					
						
					
				
			
		
		
			
				
				
			
		
	

And we can start the animation in code when our ItemsControl is creating the Items:

public TwitterItem()
        {
            // Required to initialize variables
            InitializeComponent();

            // Global variable to see how many items we already have. Alternate the animation.
            if (((App)App.Current).ItemsCount % 2 == 0)
                FlyLeftToRight.Begin();
            else
                FlyRightToLeft.Begin();
            ((App)App.Current).ItemsCount++;
        }

Here is the final version with some User Interface tweaks. When you search for an item, new items will fade in from left to right and right to left. The application will look up new items each 15 seconds.

TwitterSearchMonitor Animated Source (Visual Studio 2010)

If you’re getting a page not found error, click here to view the application.


Install Microsoft Silverlight


 

System.NotSupportedException when referencing to an assembly

11 Aug

You receive the following exception in Visual Studio 2010:

System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework.

This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.

When you try to reference binaries that were zipped on another machine you must check for blocked files:
Zip File that has blocked files

When you unlock the zip file and use the unblocked binaries, it should work.

 

Silverlight 4 Childwindow is not visible

03 Aug

When you already have some XAML code and you want to show a ChildWindow afterwards, it can be that the ChildWindow is not displayed. Normally everything should work out of the box when you start a new project and try it out in the constructor of your XAML page.

However, I found a small fix if you encounter this problem. The following code ensures that the page is fully loaded (using the Loaded Event) before we show our Child Window.

        public Page()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(Page_Loaded);
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
                ChildWindow cw = new LoginForm(this);
                cw.Show();
        }
 
 

Application manifest generation failed. The out-of-browser settings file was not specified

29 Jul

Error Message: Application manifest generation failed. The out-of-browser settings file was not specified

That error can popup in visual studio if you try to enable the OOB capabilities of silverlight. It has probably to do with Team Foundation Server or reading rights on certain files.

For some reason the *.csproj isn’t updated. You need to manually add the following line:

Under:

Add the following:

Properties\OutOfBrowserSettings.xml

Make sure you can see the OutOfBrowserSettings.xml in your visual studio project under the Properties folder. Otherwise Show all files and include the file in the project.

That should fix it!

 

RoleService not working

05 Feb

The WCF Authentication Service is great to use and it works perfectly… however, I had a lot of problems trying to get the roleservice working.

WCF Role Service is not returning any results. Anything is well configured as described on MSDN: How to: Enable the WCF Authentication Service.

I could call the role service without a problem but there weren’t any queries launched at the database.
After a long search on the internet and msdn, I finally found a small MSDN Note that says the following.

Do not call the GetRolesForCurrentUser method from code that is executing on the Web server. You call the GetRolesForCurrentUser method only as part of a WCF service. For more information about how to read a user’s roles in code that is executing on the Web server, see the GetRolesForUser method.

Why I’m using the roleservice from my ASP.Net application is hard to explain… it’s related to the fact that silverlight, sharepoint login form and custom asp.net websites are using the same webservice. We want to limit the configuration of the Membership and have our forms based user object at WCF level.

So when you’re calling this service from a client application (Silverlight), it will work. If you’re calling this from a server application like ASP.Net, you just don’t get any results back… You should use the Membership classes on your custom WCF Service in order to write your own role methods.

 

Silverlight ClientConfig File Injection

10 Jan

Although it was fun to create this one. Jermemy Likness wrote a nice article about constructing your service configuration dynamically. It’s an easy solution that I saw too late! You can find it in detail here: http://csharperimage.jeremylikness.com/2009/07/abstracting-wcf-service-calls-in.html

For development, you are probably pointing to your localhost when you need to call your webservices. When you have a scenario where you are not sure about the endpoint service URLs of your silverlight application, you need to change the ServiceReferences.ClientConfig file manually (or make it configurable in code, but we don’t know the URLs anyways…) after it has been packaged in a XAP file. Also if you’re working with HTTPS in silverlight, you need to change the ClientConfig file in order to work with Transport Security. If you have to deploy your XAP file to a lot of machines (or just a lot of times) you always need to perform 6 steps:

  • Rename your XAP file to zip
  • Extract the zip file to a folder
  • Edit the ServiceReferences.ClientConfig
  • Add the folder contents to a zip file
  • Paste the ZIP file in the ClientConfig folder and delete your old one
  • Rename the zip file to XAP

To avoid those steps, I made a little WPF application. It can perform all of these steps for you. You can also run it from the command line so you can automate everything (just a change in your clientconfig to point to the right service is required).

This is the application when you double click the EXE file.
Startup Screen (GUI Mode)

You can drag and drop your files in the window to load your XAP and/or ServiceReferences.ClientConfig file. If you do not specify a ClientConfig, you need to paste your config text in the textbox. The application will automatically pick it up and inject a new ServiceReferences.ClientConfig file for you. By default the application will backup your old XAP file. If there is already a backup, it will add an increasing value before the extension.

You can also use the application in Command Line Mode. To begin, just browse to your folder and enter ServiceInjection.exe -h. You’ll see the following output:
Commandline options

A sample of a commandline execution in a batch file would be (files are in the same folder):

CD “C:\ServiceInjection\”
ServiceInjection.exe -x \MySuperSilverligtFile.xap -s \ServiceReferences.ClientConfig -b true

You can specify a full path if your files are not in the same folder:

CD “C:\ServiceInjection\”
ServiceInjection.exe -x “C:\XapFiles\MySuperSilverligtFile.xap” -s “C:\ServiceFiles\DeploymentServer1\ServiceReferences.ClientConfig” -b true

Download the application single executable:
ServiceInjection Application

Download the source project (make changes as you wish to fit your needs):
ServiceInjection Program Source

 
 

Silverlight DataGrid and DataPaging (frozen datagrid problem)

14 Dec

There are a lot of resources on the net where you can find datapaging using RIA Services. But what if you don’t want to bind to a DomainDataSource. You only want to bind to your collection and add DataPaging to your grid.

It’s fairly easy as you can read on MSDN

You just need to bind your datagrid to a PagedCollectionView.

The reason why I’m posting this is because I had trouble with my datagrid once it has been datapaged. The datagrid was frozen, I couldn’t sort, I couldn’t reorder my datagrid columns and I even couldn’t make a selection. You should make sure that your controls are on different rows in your grid.



  
  

  
  
 
 

Silverlight 3 Resource Files – Localization – Language Specification

30 Nov

Introduction

Silverlight 3 supports the use of Resource Files (*.resx) in your application (just like ASP.Net). It’s not difficult to implement but it took some time to read everything and to get it working. I have listed the links that I have used to make it working. I have also included a simple Sample Project. This is a quick overview to get you started (The headings are clickable!).

1. How to: Add Resources to a Silverlight-based Application

Add the NeutralResourcesLanguageAttribute in your Assembly Properties.cs file

[assembly: NeutralResourcesLanguageAttribute("en-US")]
OR
SelectNeutralLanguage

Add the SupportedCultures node in your project file

Do not include your Default Language you specified in the NeutralResourcesLanguageAttribute.

fr;fr-FR;

2. Localizing Silverlight-based Applications

Getting String Values in code behind

ResourceManager rm = null;

rm = new ResourceManager("SilverlightApplication.StringLibrary", Assembly.GetExecutingAssembly());

string greeting = rm.GetString("Greeting");

3. How to: Make XAML Content Localizable

Access Modifier is set to Public of your Resource File

AccessModfierPublic


Add a class with the following content (making it exposable for XAML)

public class LocalizedStrings
        {
            public LocalizedStrings()
            {

            }

            private static SilverlightApp.Resource1 resource1 = new SilverlightApp.Resource1();
            public SilverlightApp.Resource1 Resource1 { get { return resource1; } }
        };

Add a resource reference to your public Resource Object.


 

Add a Binding to your XAML element

 


If a binding is not correct (eg. key is missing in your resource file), it will not throw an exception. You will see the error as trace information (in the output window), so make sure you check for possible binding errors!

4. How to set Culture retrieved from browser (Mike Taultys):

Add those param nodes to your Silverlight Object in your aspx page.

<param name=”Culture” value=”<%=System.Threading.Thread.CurrentThread.CurrentCulture.Name %>”></param>
<param name=”UICulture” value=”<%=System.Threading.Thread.CurrentThread.CurrentUICulture.Name %>”>

Make sure you don’t have any specific culture in your Web.Config or put this inside <system.Web>


 

5. Sample Project

The sample project contains a XAML localization example and it shows some text (using code) if you click the Button. You can see the different languages if you change your browser language preferences. Download Sample Project SilverlightLocalization

 
 

Update (10/08/2011)

 

Dynamically changing your language at runtime

If you have followed the previous steps, it’s easy to change the language at runtime. Just change the CurrentThread UI Culture. Bindings will be updated immediately.

static void SetLanguage(string culture)
        {
            if (culture != System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.CultureName)
            {
                System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(culture);
            }
        }

Using localization in Modular Silverlight Application (PRISM)

  1. Add your resource files to your Common Project (the shared project that you use in all your modules).
  2. Modify the App.xaml of your Shell application to reference the Resource files. (see above (3))
  3. The XAML bindings remain the same.
  4. Call the resourceManager in the code behind in any of your modules (make sure you reference the Common project):
var rm = new ResourceManager(typeof(Project.Common.Localization.ApplicationStrings));
                rm.GetString("Main_ResourceItem_Text");

 

 
 

2104 Silverlight Initialization Error

27 Oct

There are a lot of cases when this error might occur. Most of the time it’s because of the MIME types are missing and IIS can’t handle the xap / xaml files. Anyways, those things are already properly configured in IIS 7.

When I was loading the aspx page that hosts my xap control, I got the 2104 Initialization Error. When I tried to browse directly to the xap file I got the following error:

You do not have permission to view this directory or page because of the access control list (ACL) configuration or encryption settings for this resource on the Web server.

I fixed it by adding the Network Service account to the Security of my ClientBin folder. Everything worked after that. Strange it wasn’t there at the first place.