Friday, July 10, 2009

Silverlight 3 SaveAs Dialog debugging quirk

I have been playing with the new SaveAs dialog in Silverlight 3 and discovered an odd quirk. While debugging I was getting the following exception:

System.Security.SecurityException was unhandled by user code

Message="Dialogs must be user-initiated."

From all appearances, my SaveAs dialog was being initiated from a user-initiated event. The code to open the dialog was being executed in the Click event handler of a button on my Silverlight control. The problem was... I had a breakpoint set on the line of code that performed the ShowDialog(). Once I moved the breakpoint to the next line of code everything worked.

Hope this helps anyone banging their head against the wall on this one...

(BTW...thanks Silverlight team... this was a much needed control.)

Labels: ,

Friday, April 10, 2009

Silverlight MVVM and the Silverlight Unit Test Framework

I have been working diligently the last few months on trying to integrate better test coverage into my Silverlight development.

After scouring the web and absorbing a lot of good information on Silverlight Unit Testing from posts such as these:
And integrating the Model-View-ViewModel (MVVM) presentation pattern outlined in these great posts:

I feel I have finally put together a nice example of a Silverlight control that utilizing the Microsoft Silverlight Unit Test Framework.

My example is a straight forward Login control. I think login controls make for great demo applications. They are probably only one degree of difficulty above the traditional "Hello World" example. In it's simpilest form a login control only contains two input text boxes, a button and a text message area to display feedback. This example throws in a touch of animation, because after all, it is a Silverlight application :)


You can download the code here.

Labels: , ,

Tuesday, October 7, 2008

Silverlight Styles are Immutable

Ever see this friendly message in Silverlight?

Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))

Well, one thing you might want to check is if you are setting the Style on a control more than once. Seems that Styles are immutable in Silverlight 2.0 and therefore cannot be set more than once.

Labels: ,

Wednesday, September 24, 2008

SequenceEqual is my favorite new hammer

A common programming task that many people face is comparing 2 enumerations to determine if they are equal. Ideally you would like to be able to write code like the following:

if(arrayA == arrayB)
{
//Do Stuff Here...
}

However as you know, arrayA will never equal arrayB in the code above since they are completely different objects. What you really want to know is if the values contained in arrayA are the same as the values contained in arrayB. Well, the SequenceEqual() method provides a mechanisim to do just that.

The SequenceEqual() method enumerates the two source sequences in parallel and compares corresponding elements by using the default equality comparer for TSource.

Here is a quick example showing 2 equal arrays...

string[] arrayA = new string[]{"a","b","c","d"};
string[] arrayB = new string[]{"a","b","c","d"};
string[] arrayC = new string[]{"w","x","y","z"};

bool A_Equals_B = arrayA.SequenceEqual(arrayB); //returns true;
bool A_Equals_C = arrayA.SequenceEqual(arrayC); //returns false;

Labels: , ,

Friday, August 15, 2008

Embeding Silverlight control in web page OBJECT versus EMBED

When deploying a Silverlight control on a web page, there are several options available. You can either use the asp:Silverlight control or embed the control into your HTML using either the OBJECT or EMBED HTML tags.

One interesting gotcha that I ran into was when I tried to instantiate the Silverlight plug-in using the OBJECT tag in Firefox 3.0. The plug-in would just not load, which is strange, because before I updateded to Silverlight Beta 2 everything seemed to work fine. After poking around, I found that Apple's Safari web browser doesn't currently support the OBJECT element. Instead you have to use the EMBED tag, which works equally well in IE and Firefox. Perhaphs Microsoft is playing to the lowest common denomentor in an attempt to keep Silverlight 100% cross-browser compliant?

Either way, if you use the EMBED tag to instantiate the Silverlight plug-in, there are a couple of things to take note of:
  1. Custom parameters that are defined as individual
  2. Alternative content that displays when the Silverlight plug-in is missing will need to be wrapped in a NOEMBED element.
Here are 2 seperate implementations of a Silverlight control. One using OBJECT tag and the other using the more compliant EMBED tag.

OBJECT Implementation

<object type="application/x-silverlight" id="silverlightControl" width="390" height="100">
<param name="background" value="Yellow">
<param name="source" value="Chapter1.xaml">
<!-- Alternative content: -->
This content requires Silverlight.
<a href="http://www.microsoft.com/silverlight/downloads.aspx">
Get it Here.</a>
</object>

EMBED Implementation

<embed type="application/x-silverlight" id="silverlightControl" width="390" height="100" background="Yellow" source="Chapter1.xaml">
<noembed>
<!-- Alternative content: -->
This content requires Silverlight.
<a href="http://www.microsoft.com/silverlight/downloads.aspx">Get it here.</a>
</noembed>
</embed>

Labels:

Wednesday, August 6, 2008

Identifying the differences between CallContext Data Slots

Recently I was working on a server side caching strategy for permissions data. The key to the strategy was to place a user's permissions returned from a database call into the CallContext of WCF service. The code to do this looked something like this...

CallContext.SetData("permissionsKey", myPermissionsData);

All subsequent requests for permissions data would then be returned from the CallContext's cache permissions, thereby saving me from having to make redundant database calls for data that I already have.

myPermissionsData = (PermissionData)CallContext.LogicalGetData("permissionsKey")

Simple caching strategy...

During my testing I found that my cached data was not being returned. After further investigation I realized that I was setting the data using the CallContext's SetData method, but I was getting the data using the CallContext's LogicalGetData method. Come to find out, these are not the same. Seems there is a LogicalGetData method, LogicalSetData method, GetData method and SetData method on the CallContext object. So, it was a simple fix to use the LogicalSetData method in conjunction with the LogicalGetData method when implementing my caching strategy.

But why are there two methods that seemingly do the same thing? The documentation on MSDN doesn't really specify the differnce between the two.

Well... after doing some resarch and finding a post by Lucian Bargaoanu on the subject it seems that the difference has to do with AppDomains. Come to find out there is a LogicalCallContext and an IllogicalCallContext. LogicalCallContext will flow across appdomains. It will do this regardless of what type of object you have placed in context. The object doesn't have to implement ILogicalThreadAffinitive. When you call SetData with an ILogicalThreadAffinitive object, the data is set in the LogicalCallContext. When you call GetData it will first look in the LogicalCallContext and then in the IllogicalCallContext. You cannot have the same key in both CallContext(s).

In summary, objects stored using SetData will only flow across AppDomains if they implement ILogicalThreadAffinitive. Objects stored in LogicalSetData will flow across AppDomains even if they don't implement ILogicalThreadAffinitive. LogicalSetData handles seems to handle the ILogicalThreadAffinitive implementation for you.

Labels: , , , ,

Tuesday, July 29, 2008

Cool LINQ Tool

There is a cool LINQ tool called LINQPad available from O'Reilly.

It is pre-loaded with a bunch of great examples from C# 3.0 In a Nutshell by Joseph Albahari and
Ben Albahari

Check it out...

Labels: , , ,