About Me
I'm a Software Engineer specialized in Microsoft technology with a special interest for Silverlight. Since 2007 I work for Rubicon as a Software Engineer.
|
Posts Tagged ‘Technology’
|
|
|
Mark Monster
June 24th, 2010
.NET, Phone, Silverlight, Technology
|
|
About half a year ago I created a Blend behavior to capture usage information of a Silverlight application. But what’s next, in the near future we will have Windows Phone 7, and we can write very nice applications by using the Silverlight platform.
Although the platform is the same, you won’t be able to make use of the Blend behavior I’ve written before. Because this Blend behavior makes use of scripting inside the hosting html page. There simply is no page that hosts your Silverlight application. This is a similar problem we face when a Silverlight application is running out-of-browser, but back to the phone.
Solution Direction
To connect to Google Analytics I need to have a html page that contains a script that calls into Google Analytics to track events. So somehow I need to connect a Windows Phone 7 app to this html page.
Solution Implementation
I started off with the html page, and made it as small as possible, no content, only the scripting part.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Windows Phone 7 - Application Tracking</title>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-xxxxx-x");
pageTracker._trackPageview();
function trackEvent(category, action, label) {
pageTracker._trackEvent(category, action, label);
}
</script>
</head>
<body>
</body>
</html>
I hosted it somewhere so it’s accessible through the internet. If you copy-paste this code please make sure that you fill in your own Google Analytics tracking code.
I’ve seen some code examples where Windows Phone 7 apps were hosting a webbrowser and where the app was communicating to the page hosted in the app. So that’s where I began as well.
Add a WebBrowser control to the MainPage.xaml, I named it trackingBrowser
<browser:WebBrowser x:Name="trackingBrowser"/>
Make sure that scripts are enabled on the WebBrowser control
In the end it’s not required to make it visible at all so we can set the Visibility to Collapsed. If you’re not comfortable with not showing the browser during development you can of course leave the browser visible.
The resulting xaml will look similar to this.
<browser:WebBrowser x:Name="trackingBrowser"
IsScriptEnabled="True"
Visibility="Collapsed" />
The WebBrowser needs to load the create html page. So in the Loaded event of the containing page I set the url of the WebBrowser.
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
trackingBrowser.Navigate(new Uri("http://change-to-your-domain.com/tracking.htm"));
}
As soon as the WebBrowser navigated to this url I want to execute the trackEvent inside the html page. To call Javascript on a WebBrowser control you will have to make use of the InvokeScript method. Because the Navigated event doesn’t come back to the UI Thread we will need to make use of the Dispatcher to actually call the trackEvent method.
trackingBrowser.Navigated += (s, args) =>
Dispatcher.BeginInvoke(
() => trackingBrowser.InvokeScript("trackEvent",
"WindowsPhoneExperiment",
"Load",
"On Loading of Application"));
For the sake of the experiment I also added a button to the form to track events on button click. The event handler for the button-click looks like this.
private void button1_Click(object sender, RoutedEventArgs e)
{
trackingBrowser.InvokeScript("trackEvent",
"WindowsPhoneExperiment",
"Click",
"On Click of a Button");
}
That’s all, and now we wait…
Result
It’s very important to view the result. It will take some time before the Google Analytics stats are working. I waited a day before I looked at the stats. Good to see the concept works.

Full code
MainPage.xaml
<phoneNavigation:PhoneApplicationPage x:Class="MM.Phone.Experiments.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignWidth="480"
d:DesignHeight="800"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
xmlns:browser="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.WebBrowser"
Loaded="PhoneApplicationPage_Loaded">
<Grid x:Name="LayoutRoot"
Background="{StaticResource PhoneBackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--TitleGrid is the name of the application and page title-->
<Grid x:Name="TitleGrid"
Grid.Row="0">
<TextBlock Text="MM Phone Experiments"
x:Name="textBlockPageTitle"
Style="{StaticResource PhoneTextPageTitle1Style}" />
<TextBlock Text="Analytics"
x:Name="textBlockListTitle"
Style="{StaticResource PhoneTextPageTitle2Style}" />
<Button Content="Button"
Height="70"
HorizontalAlignment="Left"
Margin="320,77,0,0"
Name="button1"
VerticalAlignment="Top"
Width="160"
Click="button1_Click" />
</Grid>
<!--ContentGrid is empty. Place new content here-->
<Grid x:Name="ContentGrid"
Grid.Row="1">
<browser:WebBrowser x:Name="trackingBrowser"
IsScriptEnabled="True"
Visibility="Collapsed" />
</Grid>
</Grid>
</phoneNavigation:PhoneApplicationPage>
MainPage.xaml.cs
using System;
using System.Windows;
using Microsoft.Phone.Controls;
namespace MM.Phone.Experiments
{
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
trackingBrowser.Navigated += (s, args) =>
Dispatcher.BeginInvoke(
() => trackingBrowser.InvokeScript("trackEvent",
"WindowsPhoneExperiment",
"Load",
"On Loading of Application"));
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
trackingBrowser.Navigate(new Uri("http://change-to-your-domain.com/tracking.htm"));
}
private void button1_Click(object sender, RoutedEventArgs e)
{
trackingBrowser.InvokeScript("trackEvent",
"WindowsPhoneExperiment",
"Click",
"On Click of a Button");
}
}
}
tracking.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Windows Phone 7 - Application Tracking</title>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-xxxxx-x");
pageTracker._trackPageview();
function trackEvent(category, action, label) {
pageTracker._trackEvent(category, action, label);
}
</script>
</head>
<body>
</body>
</html>
|
|
|
Mark Monster
June 11th, 2010
.NET, Phone, Silverlight, Technology
|
|
Microsoft really helps developers to implement licensing for your application. First of all everyone has probably read: “an app can only be installed through the Marketplace”. But beside this installation, an application can be tried through the Marketplace. The developer doesn’t have to write complex licensing mechanisms based on RPN strings. If you want to have limited features when the app is in Trial, it’s just one small piece of code. First reference the correct library.
The the code is really simple.
LicenseInfo licenseInfo = new LicenseInfo();
if(licenseInfo.IsTrial())
{
//Limit the application in some way
}
Yes that’s all. But how does this code behave? As far as I’ve understood so far, in the final version the IsTrial will check the license with the Marketplace. Right now the behavior is just returning “true”, so that doesn’t help our development, we can’t influence this result in any documented way right now. So I was thinking about possible solution, and remember the Conditional Compilation Symbols.
Step 1: Create a New Solution Configuration
Make sure that you use Copy settings from “Debug” and “Create new project configurations”.
Step 2: Change Project Properties
Add a Conditional Compilation Symbol, for example: “FULL_VERSION”
Step 3: Use this Compilation Symbol
LicenseInfo licenseInfo = new LicenseInfo();
#if FULL_Version
if (false)
{
//Full Version so this code is not executed.
#else
if(licenseInfo.IsTrial())
{
//Trial Version
#endif
}
Step 4: Switch between different trial and full version
You can now switch from trial (Debug) to full (Debug Full Version) and back again using the Solution Configuration Selector
Hope this helps people who want to develop trial and full versions of their apps.
|
|
|
Mark Monster
May 8th, 2010
.NET, Silverlight, Technology
|
|
I’ve been experimenting with the PathListBox and wanted to create a better experience for selecting an item in the ListBox. The standard way to select an item in a ListBox is by clicking on it, but in some situations you want to select an item by just hovering over the item. I explicitly say some situations, because I wouldn’t want to fire up the discussion that hovering over an item isn’t the same as explicitly clicking on an item to select it.
First requirement for me was to have something that didn’t require me any coding when I want to apply it more than once. So for me the idea of writing a Behavior or TriggerAction does make sense.
Second requirement, should work any any regular ListBox but also on the PathListBox.
Third, should work with data binding.
Setting up the structure
So I started creating a Behavior that can be associated with any FrameworkElement and could be applied in the DataTemplate for example. You have to reference the System.Windows.Interactivity assembly to start.
public class SelectElementOnHover : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
AssociatedObject.MouseEnter += AssociatedObject_MouseEnter;
}
private void AssociatedObject_MouseEnter(object sender, MouseEventArgs e)
{
...
}
protected override void OnDetaching()
{
AssociatedObject.MouseEnter -= AssociatedObject_MouseEnter;
}
}
So we now have a behavior that reacts on the MouseEnter. What to do next?
Find my parent ListBox
I have to find my parent ListBox to enable me to set the SelectedItem of that ListBox. In runtime this item should always be a child of a ListBox. But most probably it’s not the direct child of a ListBox.
So I wrote a small recursive function that get’s the parent element until we’ve found the ListBox.
public ListBox FindListBox(FrameworkElement element)
{
DependencyObject parent = VisualTreeHelper.GetParent(element);
if (parent == null)
return null;
if (parent is ListBox)
return parent as ListBox;
return FindListBox((FrameworkElement)parent);
}
Blending it all together
When we combine this recursive function with the rest of the Behavior we’ll be able to set the SelectedItem of the ListBox on Hover.
public class SelectElementOnHover : Behavior<FrameworkElement>
{
private ListBox _parentListBox;
protected override void OnAttached()
{
AssociatedObject.MouseEnter += AssociatedObject_MouseEnter;
}
private void AssociatedObject_MouseEnter(object sender, MouseEventArgs e)
{
SelectElement();
}
protected override void OnDetaching()
{
AssociatedObject.MouseEnter -= AssociatedObject_MouseEnter;
}
private void SelectElement()
{
FrameworkElement element = AssociatedObject;
if (_parentListBox == null)
_parentListBox = FindListBox(AssociatedObject);
if (element != null && _parentListBox != null)
{
_parentListBox.SelectedItem = element.DataContext;
}
}
public ListBox FindListBox(FrameworkElement element)
{
DependencyObject parent = VisualTreeHelper.GetParent(element);
if (parent == null)
return null;
if (parent is ListBox)
return parent as ListBox;
return FindListBox((FrameworkElement)parent);
}
}
You can now easily use it in Blend with Drag and Drop, but you can also make use Xaml to attach the Behavior to an element.
<DataTemplate x:Key="ShowCasesItemTemplate">
<StackPanel RenderTransformOrigin="0.5,0.5">
<local:CompanySelector x:Name="companySelector" d:IsPrototypingComposition="True"
RenderTransformOrigin="0.5,0.5">
<i:Interaction.Behaviors>
<Behaviors:SelectElementOnHover />
</i:Interaction.Behaviors>
</local:CompanySelector>
</StackPanel>
</DataTemplate>
What if I want to delay the selection behavior?
I understand that some people would want to delay the selection in such a way that an item doesn’t get selected if the item isn’t hovered for more than x milliseconds. Below you can read the full source code for a Behavior that implements a Delay (configurable in Xaml and Blend of course).
public class SelectElementOnHover : Behavior<FrameworkElement>
{
public static readonly DependencyProperty DelayProperty = DependencyProperty.Register("Delay", typeof (int),
typeof (
SelectElementOnHover),
new PropertyMetadata(0));
private ListBox _parentListBox;
private DispatcherTimer _timer;
public int Delay { get; set; }
protected override void OnAttached()
{
_timer = new DispatcherTimer();
_timer.Tick += (sender, args) => SelectElement();
AssociatedObject.MouseEnter += AssociatedObject_MouseEnter;
AssociatedObject.MouseLeave += AssociatedObject_MouseLeave;
}
private void AssociatedObject_MouseLeave(object sender, MouseEventArgs e)
{
_timer.Stop();
}
private void AssociatedObject_MouseEnter(object sender, MouseEventArgs e)
{
if (Delay == 0)
SelectElement();
else
{
_timer.Interval = new TimeSpan(0, 0, 0, 0, Delay);
_timer.Start();
}
}
private void SelectElement()
{
FrameworkElement element = AssociatedObject;
if (_parentListBox == null)
_parentListBox = FindListBox(AssociatedObject);
if (element != null && _parentListBox != null)
{
_parentListBox.SelectedItem = element.DataContext;
}
}
public ListBox FindListBox(FrameworkElement element)
{
DependencyObject parent = VisualTreeHelper.GetParent(element);
if (parent == null)
return null;
if (parent is ListBox)
return parent as ListBox;
return FindListBox((FrameworkElement) parent);
}
protected override void OnDetaching()
{
AssociatedObject.MouseEnter -= AssociatedObject_MouseEnter;
AssociatedObject.MouseLeave -= AssociatedObject_MouseLeave;
}
}
If you like behaviors you might want to check out also my Google Analytics Silverlight Usage Tracking Behavior.
|
|
|
Mark Monster
April 2nd, 2010
.NET, Community, Silverlight, Technology
|
|
Yesterday I received an e-mail from Microsoft.
Congratulations! We are pleased to present you with the 2010 Microsoft® MVP Award! This award is given to exceptional technical community leaders who actively share their high quality, real world expertise with others. We appreciate your outstanding contributions in Silverlight technical communities during the past year.
It feels good to be awarded for the work in the community in the past year. I’ve been blogging here and answered questions on the Silverlight.net forums. Also I got more involved in the local community by being one of the founders of the Dutch Silverlight & Expression Insiders User Group. And specially last Tuesday and Wednesday, you could find me at the Ask The Experts stand during the DevDays 2010.’
Most of all, I like being involved in the Silverlight community. I’m very addicted to Silverlight so I guess the future will be at least as much Silverlight community involvement as last year.
|
|
|
Mark Monster
March 16th, 2010
.NET, Phone, Silverlight, Technology
|
|
Yesterday Microsoft made all the development tools for Windows Phone 7 available. The development tools are a combination of Visual Studio and Blend. Since the introduction of Blend 3 and it’s extra tool Sketchflow, I’m really fond of making prototypes. So the first thing I did when I installed all the Windows Phone 7 tools, is look for a Windows Phone Sketchflow project. There are only two types of projects: Windows Phone Application and Windows Phone Data-drive Application (MVVM). Sadly no Sketchflow project. So let’s look at how we could hack, to get our a Sketchflow Windows Phone project.
A Windows Phone Application with a Sketchy style
I first created a Windows Phone Application and wanted to see if it is possible to include the Silverlight Sketch styles. The Silverlight Sketch styles are included in the Microsoft.Expression.Prototyping.SketchControls.dll which can be found in C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\Silverlight\v4.0\Libraries.
Also from another SketchFlow project I copied SketchStyles.xaml, where I had to remove all the TabPanel, TabItem related styles, because they aren’t support by Windows Phone. Similar for the ScrollViewer control, where the compiler was complaining as well.
Next step was to make use of one of the styles, to see if it was working. So I amended one of the controls to TitleCenter-Sketch as the style instead of PhoneTextPageTitle2Style. So this text block looks like this afterwards.
<TextBlock Text="page title" x:Name="textBlockListTitle" Style="{StaticResource TitleCenter-Sketch}"/>
So let’s run it, to see how it looks in the emulator. Would be nice if it shows the Sketch-font. But it didn’t.
If you have other ideas to get this working please let me know, because it’s interesting to be able to sketch Windows Phone 7 applications as well.
|
|
|
Mark Monster
February 8th, 2010
.NET, Patterns, Silverlight, Technology
|
|
In step 2 I explained about the Architecture of MeXperience I had in mind. This article explains the implementation of the pipes and filters pattern to filter the list of experience objects. I will start to tell that my implementation is based on an article from Oren Eini.
The Filter
In MeXperience there are currently only two types of filters: by tag and by role. But I could think about others like a filter by year of experience.
The idea of the filter in the pipes and filters patterns is to have a simple operation, and a lot of combine simple operation in one pipeline make a complex operation.
My filters are also used as objects to represent an item in the TagCloud. This is my base.
public abstract class CloudItem
{
public CloudItem()
{
Weight = 1;
}
public int Weight { get; set; }
public string Name { get; set; }
public abstract IEnumerable<Experience> Filter(IEnumerable<Experience> experiences);
}
Yes I know it’s abstract and there’s no filter implementation. First the signature, there’s an enumeration of experiences coming as input, and there’s an enumeration as output. Let’s see one of the implementations, the of CloudItemTag.
public class CloudItemTag : CloudItem
{
public override IEnumerable<Experience> Filter(IEnumerable<Experience> experiences)
{
foreach (Experience experience in experiences)
{
if (experience.Tags.Where(t => t.Name == Name).Count() > 0)
yield return experience;
}
}
}
The Filter implementation is a simple loop through the experiences, and if the experience corresponds to the filter it will yield return this experience.
You can probably figure out how the CloudItemRole would look like. These filters are simple, let’s combine the pipeline of filters.
The Pipeline
Code explains more than words.
private IEnumerable<Experience> ApplyFilter(IEnumerable<CloudItem> filter)
{
if (filter == null)
return _experiences;
IEnumerable<Experience> current = _experiences;
foreach (CloudItem filterItem in filter)
{
current = filterItem.Filter(current);
}
IEnumerator<Experience> enumerator = current.GetEnumerator();
while (enumerator.MoveNext()) ;
return current;
}
Alright a little bit of explanation. First we start with the list of filters to apply, if the list is null we will not filter, else we will start with chaining all filters together in line 8. After everything is chained together we see all the magic happen in line 11. Until line 11 no filter has been executed, but by iterating through the experiences filter chain we will get a filtered list of experiences.
What’s to come?
There will at least be one more article on the MVVM implementation, but this is how it’s going to look like. Or look at this video.

|
|
|
Mark Monster
January 28th, 2010
.NET, Silverlight, Technology
|
|
It’s already more than a year ago since Tim Heuer published his article on Event tracking in Silverlight. Since that time we’ve got Silverlight 3 and Silverlight 4 beta. So it’s time for a different implementation that can even be used by non-coders. This article will make use of Silverlight 4 beta, but in the end almost everything works on Silverlight 3 as well.
The idea
Create an Expression Blend Behavior that does all the tracking for me!
The implementation – Some Javascript
Blend Behaviors are extremely easy to use. Designers can use them without having knowledge on code and besides that they don’t dirty the business flow of the code. Also Behaviors can be used very easily in combination with DataTemplates and BindingExpressions.
Let’s start with the very beginning. On the html-page there needs to be some Javascript from Google Analytics to start the Analytics script.
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try{
var pageTracker = _gat._getTracker("UA-xxxxxx-x");
pageTracker._trackPageview();
} catch(err) {}
</script>
This is the generic Google Analytics script to start the normal tracking. Please make sure that you replace xxxxxx with your own Tracking Code you received from Google. The documentation around Tracking Events is very good. The important part is that we need to call a Javascript function from Silverlight. I have wrapped the Google Analytics Track Events call in my own Javascript function.
function trackEvent(category, action, label) {
pageTracker._trackEvent(category, action, label);
}
But this will directly call into Google Analytics, which is very difficult to test because the data will arrive but the stats aren’t real-time. That’s why I created a small test version of this function that shows an alert.
function trackEvent(category, action, label) {
alert(category + ", " + action + ", " + label);
}
Alright we now have done all the Javascript stuff, for now I will be using the test version of trackEvent because we’re in the development stage. Let’s continue with the implementation of the behavior.
The implementation – Behavior
There are a few different types of behavior that can be created: Behavior<T>, TriggerAction<T>, TargettedTriggerAction<T>. I won’t explain every type of behavior, but for the implementation of our Google Analytics Tracking behavior I chose fore TriggerAction<T>. I did this because of the flexibility in events which a TriggerAction can react on, besides that this specific behavior won’t change anything in the Silverlight application itself, it will just call out to a Javascript function. To start with the behavior you will first have to add a reference to System.Windows.Interactivity.dll. You can find this library in: C:\Program Files (x86)\Microsoft SDKs\Expression\Blend 3\Interactivity\Libraries\Silverlight\.
public class TrackEventAction : TriggerAction<UIElement>
{
protected override void Invoke(object parameter)
{
try
{
HtmlPage.Window.Invoke("trackEvent", new object[] {Category, Action, Label});
}
catch
{
}
}
}
The implementation is simple, just a call out to the Javascript function trackEvent, and three parameters. I explicitly put everything in a try catch swallow statement, because I don’t want a failure in this tracking behavior to cause problems in the application. Further on I made it of type UIelement because in that case all UI elements can Track Events. You can see that the parameters for the call to the Javascript function are properties: Category, Action and Label. I explicitly didn’t put in the code, because the code is straight forward, they are DependencyProperties. Full Code is collapsed below ;-).
public class TrackEventAction : TriggerAction<UIElement>
{
public static readonly DependencyProperty CategoryProperty =
DependencyProperty.Register("Category", typeof (string),
typeof (TrackEventAction),
new PropertyMetadata("Silverlight.Event"));
public static readonly DependencyProperty ActionProperty =
DependencyProperty.Register("Action", typeof (string),
typeof (TrackEventAction),
new PropertyMetadata("Unknown Action"));
public static readonly DependencyProperty LabelProperty =
DependencyProperty.Register("Label", typeof (string),
typeof (TrackEventAction),
new PropertyMetadata("Unknown Action fired"));
public string Category
{
get { return (string) GetValue(CategoryProperty); }
set { SetValue(CategoryProperty, value); }
}
public string Action
{
get { return (string) GetValue(ActionProperty); }
set { SetValue(ActionProperty, value); }
}
public string Label
{
get { return (string) GetValue(LabelProperty); }
set { SetValue(LabelProperty, value); }
}
protected override void Invoke(object parameter)
{
try
{
HtmlPage.Window.Invoke("trackEvent", new object[] {Category, Action, Label});
}
catch
{
}
}
}
The implementation - Let’s use it
Like any other TriggerAction we can add the Interaction.Triggers element to some UIElement. The below example combines Binding in a DataTemplate.
<DataTemplate>
<Button>
<ContentControl Content="{Binding Name}"/>
<Interactivity:Interaction.Triggers>
<Interactivity:EventTrigger EventName="Click">
<GoogleAnalytics:TrackEventAction Category="MeXperience.CloudFilter" Action="{Binding Name, StringFormat='Filter.Remove[\{0\}]'}" Label="{Binding Name, StringFormat='Remove filter for \{0\}'}" />
</Interactivity:EventTrigger>
</Interactivity:Interaction.Triggers>
</Button>
</DataTemplate>
In this example I used the Click-event but it could have been any other event as well, just use the different event name and you’re done. If you’re making use of Silverlight 3, be aware that the StringFormat part of the Binding Expression doesn’t exist, if you remove it everything else will be working fine.
After some days you will get data in Google Analytics which will look something like this.

|
|
|
Mark Monster
January 17th, 2010
.NET, MEF, MVVM, Patterns, Silverlight, Technology
|
|
Besides the purpose of the application itself, I want to make sure I expand my knowledge on Silverlight. This would be especially on the architecture of Silverlight applications.
Architecture - MVVM
I’ve read quite a lot of articles on MVVM, but there weren’t many article series that were as complete as the series on RIA, MEF and MVVM by Shawn Wildermuth (1,2,3,4). I have no intend to write an article or series on MVVM because it’s not really in my fingers yet. But to know more on MVVM please read the fantastic series by Shawn. But then again my intend is to make use of MVVM for MeXperience. The idea is to introduce two ViewModels (please let me know if you’d advice a different setup for ViewModels).
1. The ExperienceFilterViewModel, which supports showing all experience-tags and the ability to form a filter.
2. The ExperienceViewModel, which has control over all experience-parts that are found in the data store and can interact independent from the filter but can have filters applied as well.
Because I chose to use the articles by Shawn as my knowledge base for MVVM, I will make use of the same components: MEF and MVVM Light Toolkit. If you have suggestions for other libraries, I’m interested, but this will be my start.
Architecture – Pipes and Filters
For the purpose of filtering the experience I want to introduce a Pipes and Filters design pattern. I know it’s not absolutely necessary but it makes sense for this purpose.
Architecture – Experience Data Store
It’s very standard to give an application a database for it’s data store. But to be honest there are many situation where a database isn’t the best choice. So in this occasion I think an xml file containing all the experience information will do. For now MeXperience will only be about the presentation of the experience. Maybe some time in the future there will be an application to edit this xml file.
User Interface Components
I’ve searched around the web (being aware of some licenses I won during Silverlight Control Builder Contest) for some User Interface components that could really help implementing the User Interface that I proposed in my prototype in the first part of my series.
 
The first piece of User Interface that I want to cover is the TagCloud. But when I search on Google, I first find a component on Codeplex which has tight integration with WCF, second result is an article from my own hand (July 2008), third is the very nice 3D-Tagcloud by Peter Gerritsen. But in the end all that looks like the best suitable component is the Silverlight Tag Cloud by Infragistics (I’m lucky to have the license).
Further on the experience table-tile-view thingy. After some investigation I’m sure, it’s called a Tile View. Both Infragistics and Telerik have such a control. But because I already found a Tag Cloud by Infragistics I will use the Infragistics controls. Hope this will be a good choice.
|
|
|
Mark Monster
January 8th, 2010
.NET, Silverlight, Technology
|
|
Every now and then I have some ideas. That’s also the main reason why I created a Windows Mobile application to support at least the storage of my ideas to be sure that those ideas don’t get lost. Some ideas will never be more than just an idea. One of my latest ideas was the below idea. I want to implement this idea, in the time I have (very little).
MYdea: MeXperience
I want application that can show my work experience in an interactive way. I was thinking tag-cloud, tiles, details, photo.
Yes a tag-cloud with the different technologies and roles that have been covered in the experience. If you would click on any item in the tag-cloud, it would be part of the filter. The filter would be applied to the experience.
I wanted to show blocks of experience, to offer a different experience than what people are used to in common curricula vitae. And when you click on a block, the details of the block would be shown.
Maybe more features would be appear in the future, but this is it for now.
Prototype
So what I did was, start with Sketch Flow. Sketch Flow is my favorite tool for prototyping and specially is very easy to use. Please look at below screens for the result.

What do you think about this prototype? Do you have ideas for features that should be included?
Alright, lets hope to find some time for discussing architecture and the basic setup, and probably even more to follow.
|
|
|
Mark Monster
December 2nd, 2009
.NET, Silverlight, Technology
|
|
I’ve been writing on Credentials in context of Silverlight for some time now. I didn’t like the options that were available to secure services and allow integration with Silverlight. For some history search for “credentials” on my blog.
July 2008 – Silverlight 2 – A series of articles on possible (failed) work-arounds for getting Credentials in Silverlight.
March 2009 – Silverlight 3 – WebClient, WebRequest and WCF calls using Credentials?
July 2009 – Silverlight 3 – Did we get support for Credentials?
In Silverlight 3 we already got the property Credentials on both WebClient and WebRequest. But sadly there still was no implementation available. After the launch of Silverlight 3 Tim Heuer already commented that the feature for credentials was being considered for future versions. Very nice, specially because we finally got it in Silverlight 4 (beta).
Support for Credentials has come to the ClientHttp stack, so you must make sure you register the http prefix to be using ClientHttp stack.
WebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp);
Besides that we also need to make sure that we set the property UseDefaultCredentials to false. Depending on whether you make use of a WebRequest or use a WebClient it will look like this.
request.UseDefaultCredentials = false;
WebRequest with Credentials
When you want do a simple webrequest to a url that’s secured using credentials this can look like this.
private void DoWebRequestWithCredentials()
{
WebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp);
var request = WebRequest.Create(new Uri("http://mark.mymonster.nl")) as HttpWebRequest;
request.Credentials = new NetworkCredential("username", "password");
request.UseDefaultCredentials = false;
request.BeginGetResponse(ResponseCallBack, request);
}
private void ResponseCallBack(IAsyncResult ar)
{
var request = ar.AsyncState as HttpWebRequest;
var response = request.EndGetResponse(ar) as HttpWebResponse;
using(var reader = new StreamReader(response.GetResponseStream()))
{
string result = reader.ReadToEnd();
}
}
WebClient with Credentials
The WebClient has the same properties. Works same as providing credentials to a WebRequest, that’s really nice.
private void DoWebClientDownloadWithCredentials()
{
WebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp);
var client = new WebClient();
client.Credentials = new NetworkCredential("username", "password");
client.UseDefaultCredentials = false;
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(new Uri("http://mark.mymonster.nl"));
}
private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
string result = e.Result;
}
WCF?
Sadly during tryout I didn’t find the credentials property to be part of ClientBase<T>. So for WCF we still have to wait some time to get credentials, or will it be part of final Silverlight 4?
What happens when you provide the wrong credentials?
I tried to make a webrequest with the wrong credentials. I expected an exception similar to “Unauthorized”, but instead I received a WebException with the message “The remote server returned an error: NotFound.”. I hope the team changes this to a more meaning full exception, because this makes debugging very hard.
|
|