How to implement INotifyPropertyChanged without strings and support Asynchronous Notification

In this post I want to show you an alternative way of implementing INotifyPropertyChanged with a nice, string-less way of raising the PropertyChanged event.

It implements usual INotifyPropertyChanged infrastructure and allows you to have strongly-typed property notifications (instead of mangling with strings). Also because PropertyChanged event can be raised from asynchronous code (ie raised from different thread than main) it needs to be dispatched to the main thread which is done by using simple utility class Call and it’s OnUIThread() routine.

For example in your ViewModel you want to create a property call “MyProp”, and on line 12 instead of using a literal string you now use a strongly type property with intellisense support from Visual Studio:

    public class MyViewModel : ViewModelBase
    {
        private string myProp;
        public string MyProp
        {
            get { return myProp; }
            set
            {
                if (this.myProp != value)
                {
                    myProp = value;
                    NotifyOfPropertyChange(() => MyProp);
                }
            }
        }
    }

First, you create a base class ViewModelBase.cs like this:

public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        public void NotifyOfPropertyChange(string propertyName)
        {
            Call.OnUIThread(() => PropertyChanged(this, new PropertyChangedEventArgs(propertyName)));
        }

        public void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property)
        {
            var lambda = (LambdaExpression)property;

            MemberExpression memberExpression;
            if (lambda.Body is UnaryExpression)
            {
                var unaryExpression = (UnaryExpression)lambda.Body;
                memberExpression = (MemberExpression)unaryExpression.Operand;
            }
            else
            {
                memberExpression = (MemberExpression)lambda.Body;
            }

            NotifyOfPropertyChange(memberExpression.Member.Name);
        }
    }

plus a helper class Call.cs that:

    public static class Call
    {
        public static void OnUIThread(Action action)
        {
            Dispatcher dispatcher = Deployment.Current.Dispatcher;

            if (dispatcher.CheckAccess())
            {
                action();
                return;
            }

            dispatcher.BeginInvoke(action);
        }
    }

Using VisualStateManager/Storyboard in MVVM

A recurring problem with MVVM is how to incorporate animations in a nice MVVM way. The problem is that StoryBoards need to be started from the view, since they are usually configured in XAML. This means that the ViewModel needs a reference to the view, in order to tell it when the animation should start. Keeping a reference from the ViewModel to the View is obviously “not done” in the MVVM pattern. In this post I’m going to show how you can use the VisualStateManager to start animations and incorporate it in the MVVM pattern, without keeping a reference from the ViewModel to the View.

1st a create VisualStates.cs class which implement an attached property

    public static class VisualStates
    {
       public static readonly DependencyProperty CurrentStateProperty =
           DependencyProperty.RegisterAttached("CurrentState", typeof(String), typeof(VisualStates), new PropertyMetadata(TransitionToState));

        public static string GetCurrentState(DependencyObject obj)
        {
            return (string)obj.GetValue(CurrentStateProperty);
        }

        public static void SetCurrentState(DependencyObject obj, string value)
        {
            obj.SetValue(CurrentStateProperty, value);
        }

        private static void TransitionToState(object sender, DependencyPropertyChangedEventArgs args)
        {
            Control c = sender as Control;
            if(c != null)
            {
                VisualStateManager.GoToState(c, (string)args.NewValue, true);
            }
            else
            {
                throw new ArgumentException("CurrentState is only supported on the Control type");
            }
        }
    }

2nd in the ViewModel provide a Property that will fire and NotifyPropertyChanged event

        private string _currentState;
        public string CurrentState
        {
            get
            {
                return _currentState;
            }
            set
            {
                if (value != _currentState)
                {
                    _currentState = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("CurrentState"));
                }
            }
        }

Finally in the View, attached VisualStates to the UserControl and Bind the Property in the ViewModel that will cause the change in Visual State

<UserControl
    ...
    xmlns:mvvm="clr-namespace:MVVMSupport;assembly=MVVMSupport"
    DataContext="{StaticResource mainPageViewModel}"
    mvvm:VisualStates.CurrentState="{Binding CurrentState}"
    >
    <Grid x:Name="LayoutRoot" Background="White">
    	<VisualStateManager.VisualStateGroups>
    		<VisualStateGroup x:Name="States">
                    ...

Via http://blogs.infosupport.com/blogs/alexb/archive/2010/04/02/silverlight-4-using-the-visualstatemanager-for-state-animations-with-mvvm.aspx

An alternative without using Attached Property is using Blend 4’s PropertyChangedTrigger or DataTrigger

  • PropertyChangedTrigger will fire whenever there is a change in value
  • DataTrigger allow you to specify a condition and it will fire only when the condition matches

Handling and Troubleshooting WCF Faults in Silverlight

image

Shows you how to identfy the problems with your WCF services and how to fix them. He covers several topics including these:

  • Handling Faults: How to get exceptions propogated from the sderver to Silverlight e.g. using FaultBehavior (more detail about FaultBehavior go here @msdn)
  • How to use Fiddler to use with WCF  – replace localhost with ipv4.fiddler in SerivceReference.ClientConfig and Browser’s address bar
  • Using the new relative address feature in Silverlight 4’s ServiceReference.Clientconfig e.g. ..\xyz.svc

Via http://channel9.msdn.com/Shows/SilverlightTV/Silverlight-TV-46-Whats-Wrong-with-my-WCF-Service

GPS Simulator for Windows Phone 7

image

You want to develop applications that use the GPS on your Windows Phone 7.  You may not have a physical device.  Or even if you do, sometimes it’s not very convenient to test out your GPS based software by walking around with your phone.  To help out with this type of development, here is a very simple and crude GPS Simulator to use in your WP7 apps.  There are two components to the simulator, the first is a Silverlight desktop hack job application that can be used to construct your route and sample data points.  The second is a class that you include in your WP7 app called FakeGps .

continue @ http://new.efficientcoder.net/2010/09/gps-simulator-for-windows-phone-7.html

A guide to cleaner XAML with custom namespaces and prefixes

Before:

   <UserControl x:Class="Sandworks.Silverlight.NamespaceExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:my="clr-namespace:Sandworks.Silverlight.NamespaceExample.Controls"
    xmlns:conv="clr-namespace:Sandworks.Silverlight.NamespaceExample.Converters"
    xmlns:lib="clr-namespace:Sandworks.Silverlight.NamespaceExample.ClassLibrary.Converters;assembly=Sandworks.Silverlight.NamespaceExample.ClassLibrary" >  

After:

   <UserControl x:Class="Sandworks.Silverlight.NamespaceExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sw="http://schemas.sandworks.com/sl/" > 

consolidated into 1 line xmlns:sw=…

To achieve this behavior you need to follow the next steps:

  1. Go to the project where you want to map CLR namespaces to a custom namespace.
  2. Open AssemblyInfo.cs under Properties
  3. Add the following to the top of your code: using System.Windows.Markup;
  4. Add the XmlnsPrefix and XmlnsDefinition attributes.

Example:

[assembly: XmlnsPrefix("http://schemas.sandworks.com/sl/", "sw")]
[assembly: XmlnsDefinition("http://schemas.sandworks.com/sl/", "Sandworks.Silverlight.NoNamespaceExample.Controls")]
[assembly: XmlnsDefinition("http://schemas.sandworks.com/sl/", "Sandworks.Silverlight.NoNamespaceExample.Converters")]
 

via http://www.codeproject.com/KB/silverlight/xaml_custom_namespaces.aspx

Progress Bar performance note

image

And yet another reminder: if you are using the indeterminate ProgressBar built into the Windows Phone platform, please follow this instructions to make sure you have a smooth, fluid user interface experience. You need to use a special workaround to offload the animations to the compositor thread and remember to toggle IsIndeterminate property back to false when you no longer need it.

This is super important because so many applications are doing potentially heavy processing when they are showing a progress bar like this. The performance issue is not evident in the emulator as much as on actual Windows Phone 7 devices by the way.

Tilt effect for Windows Phone controls

image

An enjoyable feature found in Windows Phone is a neat interactive effect that our designers have dubbed “tilt”. Tilt gives a little motion to standard controls during manipulations (when they’re being touched).

http://blogs.msdn.com/b/ptorr/archive/2010/08/11/updated-tilt-effect.aspx

http://msdn.microsoft.com/en-us/library/ff941094%28VS.92%29.aspx

Related Links:

Passing WCF Exception to Silverlight

Since it is not possible to catch regular exception from a WCF service in a silverlight application, there is another way to do it by using BehaviorExtensionElement.

1. On Server-side First create a behavior like this:

public class MyFaultBehavior : BehaviorExtensionElement, IEndpointBehavior
    {
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            SilverlightFaultMessageInspector inspector = new SilverlightFaultMessageInspector();
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
        }
        public class SilverlightFaultMessageInspector : IDispatchMessageInspector
        {
            public void BeforeSendReply(ref Message reply, object correlationState)
            {
                if (reply.IsFault)
                {
                    HttpResponseMessageProperty property = new HttpResponseMessageProperty();

                    // Here the response code is changed to 200.
                    property.StatusCode = System.Net.HttpStatusCode.OK;
                    reply.Properties[HttpResponseMessageProperty.Name] = property;
                }
            }
            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
            {
                // Do nothing to the incoming message.
                return null;
            }
        }
        // The following methods are stubs and not relevant.
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }
        public void Validate(ServiceEndpoint endpoint)
        {
        }
        public override System.Type BehaviorType
        {
            get { return typeof(MyFaultBehavior); }
        }
        protected override object CreateBehavior()
        {
            return new MyFaultBehavior();
        }
    }

2. On Server-side Modify you web.config:

	<system.serviceModel>
		<!--Add a behavior extension within the service model-->
		<extensions>
			<behaviorExtensions>
				<add name="myFault" type="SilverlightWCF.Web.MyFaultBehavior, SilverlightWCF.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
			</behaviorExtensions>
		</extensions>
		<behaviors>
			<!--Add a endpointBehavior below the behaviors-->
			<endpointBehaviors>
				<behavior name="myFaultBehavior">
					<myFault/>
				</behavior>
			</endpointBehaviors>
			<serviceBehaviors>
				<behavior name="SilverlightWCF.Web.MyCoolServiceBehavior">
					<serviceMetadata httpGetEnabled="true"/>
					<!--For debugging, it might be cool to have some more error information.
       to get this, set includeExceptionDetailInFaults to true-->
					<serviceDebug includeExceptionDetailInFaults="true"/>
				</behavior>
			</serviceBehaviors>
		</behaviors>
...
		<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
		<services>
			<service behaviorConfiguration="SilverlightWCF.Web.MyCoolServiceBehavior" name="SilverlightWCF.Web.MyCoolService">
				<!--Set the behaviorConfiguration of the endpoint-->
				<endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="SilverlightWCF.Web.MyCoolService" behaviorConfiguration="myFaultBehavior"/>
				<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
			</service>
		</services>
	</system.serviceModel>

3. On Server-side Throw you FaultException

        [OperationContract]
        public void Foo()
        {
            throw new FaultException("this is my Exception");
        }

4. On Client-side Catch the Exception like this:

        void serviceClient_FooCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                // In case of success
            }
            else if (e.Error is FaultException)
            {
                FaultException fault = e.Error as FaultException;
                string text =  e.Error.Message;
            }
        }

via http://www.codeproject.com/KB/silverlight/SilverlightWCFService.aspx

Microsoft Advertising SDK for Windows Phone 7

Ad SDK for developers who want to monetize their WP7 applications via advertising.

There are developers who want to sell their apps, some who want them to be free, and even more still who will want to put ads inside of their apps. The Mobile Advertising SDK is available today making is very easy for developers to generate ad revenues from their apps. The team has also released the first real-time, bid-based mobile ad exchange, allowing for revenue maximization of ad placements when they are served. Raj Kapoor has a great post talking about this release.

The SDK allow easy integration of text and banner ads into your application, and consumes ads served by Microsoft’s mobile Ad Exchange, the first bidded ad exchange for mobile.