Rants Tagged with “Silverlight 2”
Now that my ADO.NET Data Services support has been merged into the trunk of NHibernate.LINQ, I do have some caveats about using NHibernate.LINQ with ADO.NET Data Services. ADO.NET Data Services is a beta 1 product so there are some bugs and issues that you will either need to avoid or work around.
The biggest issue is around entity identity. ADO.NET Data Services must know how identity is established for objects in order to support the Data Service. It does this in a two step process:
- First it looks for attributes that describe the 'primary key'.
- Failing that, it looks for properties on the entity called ID, or ending with "ID".
The second approach is where I expect most of NHibernate projects to fall into since you really don't want to pollute your objects with technology specific information (the attributes). This approach works well except that there is a bug in the Beta 1 version of ADO.NET Data Services. If the properties are specified in a base class and the keys are specified ending in "ID" (instead of just being called "ID"), then the search for the identifiers fails and Data Services fails to want to serve these objects. For example:
public class AbstractCategory
{
public virtual int CategoryID { get; set; }
public virtual string CategoryName { get; set; }
public virtual string Description { get; set; }
public virtual byte[] Picture { get; set; }
public virtual IList Products { get; set; }
}
public class Category : AbstractCategory
{
}
}
If this is your scenario, I might suggest waiting for later build of ADO.NET Data Services to be released as this is definitely a bug not expected behavior and I have gotten word from Microsoft that it is fixed in the RTM (which isn't available yet).
The next issue is that for collections, ADO.NET Data Services must understand the types that belong in a collection. In this case our above example will not work either in that having the Products in a Category as a simple IList can't tell ADO.NET Data Services what types of objects to deal with. If we change this to an IList<Products>, it works fine. If we have to change our entities to work with ADO.NET Data Services, this is what our new Category might look like instead:
public class Category
{
public virtual int CategoryID { get; set; }
public virtual string CategoryName { get; set; }
public virtual string Description { get; set; }
public virtual byte[] Picture { get; set; }
public virtual IList<Product> Products { get; set; }
}
With these changes, ADO.NET Data Services work fine.
If you are new to ADO.NET Data Services, this blog entry may help with some debugging issues in using it:
http://wildermuth.com/2008/06/07/Debugging_ADO_NET_Data_Services_with_Fiddler2
Lastly, I want to follow up on a note that Ayende mentioned on his announcement of my examples. In his blog post, he said:
From a technological perspective, I think this is awesome. However, there are architectural issues with exposing your model in such a fashion. Specifically, with regards to availability and scalability on the operations side, and schema versioning and adaptability on the development side.
I think he's right in that there is a schema version issue here that needs to be addressed but that the availability and scalability problems are ones that would be in the underlying data model itself. Since ADO.NET Data Services are just a convenience around WCF's REST Service Model, we can scale out or up depending on our needs (as well as caching).
What I think is important is to understand the reason behind ADO.NET Data Services. It is not a model to replace typical Web Service or Message Bus architectures. Its not all that fast or efficient. Its purpose is to allow the creation of a simple model to allow communication across the firewall. What I mean is that it is meant for the AJAX and RIA developers. Its a way of communicating data to clients that run on the Internet.
Its important to understand that data you expose with ADO.NET Data Services is not magically more secure...in fact, since its meant for client-side consumption of data, you should not allow data to be exposed by ADO.NET Data Services that is sensitive. Remember, that consuming data in the client is not secure in itself. If you wouldn't feel safe consuming data in client-side JavaScript, don't expose it via ADO.NET Data Services.
UPDATE: Looks like I uncovered a ADO.NET Data Services bug in FF3. The examples will only work with IE and Safari at the moment.
After a couple of weeks on and off the project, I finally finished the first stab at adding ADO.NET Data Services support to NHibernate.LINQ. To accomplish this I've added three features:
- Support for IUpdateable to support full NHibernate CRUD.
- Support for a new Expand extension method to do eager loading via the LINQ interface. (The Expand method is similar to Entity Framework's Include method.)
- Finally, using the Expand extension method, I implemented the IExpandProvider interface to allow for expansions via the REST API.
These changes have been posted to the NHContrib project (where the NHibernate.LINQ lives) to allow the committers to validate and add it to new versions of the project. I am sure that it will need some refactoring and tweaking but the basics are done.
In addition, I'll be finishing up my discussion of implementing the IUpdateable interface pretty soon to help those of you adding this support to your projects. I'll also be blogging about how I added the IExpandProvider to help those of you trying to add that to your projects (or even to LINQ to SQL).
To prove out this new support, I've launched a new version of my Simple ADO.NET Data Services project with a NHibernate flavor. Go visit http://www.silverlightdata.com to see it working. In addition, I updated that sample to include paging support to make it a little more performant.
Let me know what you think.
In my recent class I had a student ask me about animating a brush. I quickly dove into how to animation a *color* in a brush and he indicated that isn't what he wanted. He had a resource-based brush that he wanted to switch out in the Visual State Manager. In Blend when he was setting the Brush during the animation recording of the MouseOver event but that wasn't creating a storyboard but changing the natural brush of the control. To solve this we had to dive into the XAML as Blend doesn't seem to know about the ObjectAnimationUsingKeyFrames animation type.
First a small discussion about animations. Normally animations will take a value and transition between the values. For example a DoubleAnimation that is set up to change the Opacity of a visual element from zero to one, will interpolate the values to create a smooth transition from invisible to visible. Keyframed animations support several types of interpolation including linear (the default), spline and discrete. Linear keyframes simply create a smooth transition between values. Spline keyframes allow you to shape the interpolation between the values to ease-in or ease-out the transition. Lastly, the Discrete keyframes set a value at the time of the keyframe without any interpolation.
The ObjectAnimationUsingKeyFrames animation allows you to use object instead of primitive values for your animation keyframes. The only type of keyframe allowed in the ObjectAnimationUsingKeyFrames animation are Discrete keyframes. The reason is that there is no good way to interpolate between object values. So back to our original problem, animation a Brush. In the MouseOver state, the student wanted to change the Fill of a rectangle from one resource-based Brush to another. For example, here are the brushes defined in the Resources section:
<UserControl.Resources>
<LinearGradientBrush x:Key="backBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="#FFFF0000" />
<GradientStop Color="#FFE50000"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="mouseOverBackBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="#FF006DFF" />
<GradientStop Color="#FF0064E9"
Offset="1" />
</LinearGradientBrush>
...
The student had set the backBrush to the Rectangle's fill during the design phase and wanted to set the mouseOverBackBrush during the Visual State Manager's MouseOver state. Since Blend wouldn't let us do it, we had to write the ObjectAnimationUsingKeyFrames XAML ourselves.
To do this, we created a Storyboard and an ObjectAnimationUsingKeyFrames element inside the MouseOver state (of the Visual State Manager for our Button's ControlTemplate). In the new element we specified the Storyboard.TargetName and Storyboard.TargetProperty to "theBack" and "Fill". Inside the animation, we created a DiscreteObjectKeyFrame for our one value. We just wanted to change it to the since new brush so we only needed one. We set the Keytime to "0:0:0" to specify that this should happen immediately. Lastly, we specified the StaticResource for the mouseOverBackBrush as the Value. Here's the entire MouseOver state XAML:
...
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="theBack"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0:0:0"
Value="{StaticResource mouseOverBackBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
...
We didn't need to specify another animation in the Normal state the Visual State Manager automatically handles the resetting of our value back to the original state. It just works. Here's two pictures of the button before and after the mouse over:


You can download the example here.
Short and sweet...if you are having Silvelright 2 Beta 2 issues with Firefox and media streaming, make sure you check Windows Update for a new fix. I think the OSX guys can just visit a Silverlight page to get it (using the auto-update stuff).
I was under a false impression. I've been using Twhirl for my Twitter client needs as it was the most feature complete client i could find. Twhirl requires the Adobe AiR runtime to work. I thought that AiR was a wrapper around Flex to allow desktop installation of Flex. What I didn't understand was that AiR is a runtime to allow Flex, Flash and HTML/AJAX apps to be hosted as a windowed desktop application. Interesting...so AiR isn't necessarily about Flex, but for all three platforms.
HTML/AJAX you say? Silverlight 2 is hosted on HTML. Could I do the scandalous thing and make my Silverlight 2 application run as an AiR application? It was to the SDK I ran.
With the AiR SDK in hand, I followed their walk-through to create my first small AiR app. Its an interesting model that creates AiR apps out of a bunch of resources. So, in theory Silverlight could work. Silverlight.js, .xap files, and other resources are just files. It should work...but it doesn't. The problem is that when hosted in AiR, the Silverlight ActiveX object doesn't want to be created. I am not sure if this is an issue with AiR or Silverlight. I've seen examples of other web-friendly ActiveX (or object tags) working (e.g. PDF Viewer) in AiR, so my guess is Silverlight 2.
I didn't expect to get much in the way of examples from other people, but I did expect to find some good community support for AiR...but even the Adobe public forum for AiR had zero messages (I think its broken, not empty).
So I plead to my readers: if any of you know of any good AiR resources (developer-to-developer preferred), please add a comment here. It'd be cool to actually get this to work.
We are pleased to announce that Wildermuth Consulting Services has partnered with RunAtServer Consulting of Montréal, Canada to translate our course into French. They will be giving the course in Montréal and Québec City:
- Montréal - September 5-7th, 2008
- Québec City - November 5-7th, 2008
- Montréal - November 19-21st, 2008
- Montréal - January 26-28th, 2009
If you've been waiting for a French version of the workshop, your time has come!
In this TechCrunch article, they report that Adobe has released a stripped down version of the engine that can parse the swf files and give back info that is useful for the indexing engines. Its unknown whether Google or Yahoo (the report doesn't mention Live.com as one of the search engines it gave the technology to) will use it, but I expect they will.
So the question comes up, what about Silverlight apps? Will SEO for Silverlight become a big bargaining chip? I hope Microsoft responds though with the .xap and XAML files, Silverlight is already pretty easy to consume. My one request would be that Silverlight 2 stop embedding the .xaml into the assemblies so that the search engines don't have to double dig to get to the XAML.
Now that Silverlight 2 is getting closer to a reality (and a Go-Live license) the 3rd party controls are starting to sneak out. None of these are in 'release' quality but I thought it might help to get my opinion on the current state of these controls. Some of the vendors are releasing previews of their entire Silverlight 2 suites while others are releasing teaser controls (and some are even free!).
Caveat: I don't think its fair to 'review' these suites, I have included some comments about what I like and don't like about the controls. Please don't take any of these comments as a 'review'.
In testing these, I simple was creating them ad-hoc with XAML. I did not test them with Blend at all. Here are the controls I've looked at so far (in no particular order):
ComponentOne Studio for Silverlight (M2 Preview Release):
This control suite looks like the most complete of the bunch. While I don't prefer the speed of the Tree control or the look/feel of the DataGrid, overall its a great set of tools. I particular like the input controls (e.g. MaskedEdit) and the Image Rotator. It comes with lots of examples and seems to abide by design standards pretty well. My biggest complaint is the sheer size of the library. The shared part of the library is over 500K and on top of that you layer one of a number of assembllies that contain the controls. This means that a typical app is bloated by about 200-400K (after xap compression).
DevExpress's AgDataGrid (Beta 1):
Another data grid that's been thrown into the mix, DevExpress's grid seems to perform pretty well though it is buggy with some of its implementation of ObservableColleciton...but it is Beta, right? Out of the box the Microsoft grid seems to do more than this grid but with a quick look under the covers its obvious that this is a powerful control. My only peeve is that they seem to be modeling this off their WinForms grid in its naming of common properties (e.g. DataSource instead of ItemsSource). But that's not a big complaint.
Telerik's RadControls for Silverlight 2:
I am less than blown away with these controls. This suite doesn't quite seem to know what it wants to be with a mix of different types of controls thrown together (rotating cube, video player, tree control, and uploader et al.) it seems like mix of single use controls instead of a suite for a specific market (i.e. ComponentOne seems directly aimed at Line of Business apps). For the most part the controls work as advertised but they don't behave well for measurement and arrangement (which means they are wonky in a Grid). This is the only suite that doesn't mark itself as a non-released version (there was no indication of Beta, CTP, Alpha, etc.) so I suspect its a very early cobbling of some of their controls to give us a preview of what they're capable of. In addition, there is no segmentation of their controls so you're required to use the entire 900K+ assembly even if you only need one of their controls.
Infragistics NetAdvantage for Silverlight CTP:
I used the UltraGauge and UltraChart to create a simple example using live data and was pleasantly surprised. The UltraChart was powerful and worked much like expected. The range of customization seemed deep and performance was good. The docs are a little lacking but at this point in their development they are what I would expect. The UltraGauge I was less happy with as it took a substantial amount of XAML to achieve even a simple radial gauge and setting values is not simple. This complexity is probably a benefit for customers looking for a very flexible Gauge, but for simple work it is a lot of work to get simple stuff to work.
Visifire Silverlight Charts:
The licensing (open source/free) is great. For straightforward charting, its a great solution. Two things that make me less than thrilled with it though: height/width must be specified (breaking design standards and annoying users); and will not dynamically display chart information. Adding data to the chart's series' simple does nothing. No redisplay no matter what I tried. The examples the site uses to show dynamic data involve updating external data and restarting the Silverlight application. Too bad too...
Netika Tech's GOA for Silverlight:
I decided not to review the GOA for Silverlight project as its really an implementation of Windows Forms for Silverlight and isn't really a control suite but a porting package.
Tim Heuer again to the rescue. I had started a Dynamic .xap file demo to figure out how all that dynamic .xap stuff worked when he released a new video detailing it exceptionally. Run over to Method ~ of ~ failed and see the other videos he has for you...
I've been digging into some of the open source and 3rd party controls that are becoming available for Silverlight 2. While running into some odd issues with some of them it occurred to me that there are some design guidelines that haven't been well communicated. Back in the early days of WPF I learned (though exactly where is unclear) that every control should support an empty constructor and that all properties (e.g. XAML Attributes) should have a default value. I knew this to be true but I couldn't document where it came from.
So as usual when I am stuck, I contacted Chris Sells as he was my mentor in early XAML usage. He was at MSDN at the time gathering content and helped me get the Data Binding articles as well into the Software Design Review for WPF (then Avalon). If anyone could help me figure out where I learned this, he'd know. He reminded me of the language they use internally: "Create-Set-Use". Essentially this means that the design pattern for controls is that they should work without requiring any properties:
<Grid ...>
<Rectangle />
</Grid>
You can see that the Rectangle doesn't require any properties to be valid. Of course this Rectangle has no fill brush and no stroke brush which means it will likely not be visible. But that's OK because it is valid XAML and doesn't break. The XAML for a control doesn't have to read the mind of the user, but should behave (e.g. not throw exceptions). One of the most egregious was a control that threw an exception if I failed to set the Width and Height. Worse yet, when it did throw these exceptions, it didn't tell me what *all* the properties I needed therefore it was painful to use. Width and Height are particularly problematic in this way in that by not defaulting to "Auto", showing the control in a non-Canvas container meant I needed to set "Auto" to the values which is what they should *always* be defaulted to.
Create-Set-Use happens during parsing of the XAML. This comes back to thinking of XAML as a serialization format for in-memory objects. XAML is simply a way to define what the structure of a particular document should be when its de-serialized. If you keep in mind that an Element becomes an object construction and that properties become SetValue calls, it makes it fairly clear what is happening during the parsing of the XAML itself.
As you write your own Silverlight or WPF classes that you expect to be used in XAML (this includes controls but also may be types that can be created as resources), try to keep these design ideas in mind. It will make life easier for your users.