Showing posts with label Silverlight. Show all posts
Showing posts with label Silverlight. Show all posts

Saturday, April 16, 2011

WPF Is Dead

Will Silverlight 5 replace WPF? Silverlight has been fast approaching the functionality of WPF for sometime now.  Out-Of-Browser support, arguably the richest 3D functionality in a browser, the fastest language to code line of business apps.

But Microsoft gave some pretty damming signals about Silverlight in the last 18 months.  But at MIX11 the tune seems to have changed...

http://www.infoq.com/news/2011/04/Silverlight-MIX

And this from Microsoft's Product Manager for Silverlight Scott Barnes:

“Right now there's a faction war inside Microsoft over HTML5 vs Silverlight. oh and WPF is dead.. i mean..it kind of was..but now.. funeral.”

"Right now WPF has no Microsoft Product Manager. The rise and fall of Microsoft UX Platform. My thoughts on how such an amazing potentially game changing thing, just failed due to internal politics etc."

"WPF however has more ubiquity than Silverlight today, it’s got approx. 70%+ ubiquity in Windows based machines and furthermore it’s gotten deeper traction when it comes to Independent Software Vendors (ISV’s) so it presents quite a complex problem in around investment and it’s overall future.
On one hand, it’s pretty widely known within the company that WPF has been ear marked for death for quite some time and had it not had such prolific ubiquity or ISV’s that build software used by many on it (Autodesk 3DSMAX, Visual Studio, Expression etc) it would have been taken out back and shot long ago. It simply is too hard to kill, so the only way Microsoft to date knows how is to either spend majority of its focus on convincing developers that Silverlight is the better option and/or reduce the noise around WPF altogether hoping that others will pick up on the subtle tones that it’s better you don’t adopt but under the Smokey hazed veil of the a-typical response “It depends”.
WPF has no investment, it’s kept together by a skeleton crew and its evangelism / community efforts have little to no funding attached to it. It’s dead, the question now is how is the corpse going to be buried and no amount of cheer leading will change that outcome in the near future."


So... Silverlight and HTML5 is the future of all development on the Windows platform then?

Rest in peace WPF, WinForms will be there to keep you company on the other side.

Wednesday, March 16, 2011

Windows Phone Navigation Basics

Excellent walk though in the MSDN journal by Charles Petzold on Silverlight Windows Phone Navigation.

Also some excellent demo's of Silverlight culture localisation.

Wednesday, January 5, 2011

Visual State Manager in WPF4

One of the questions I hear as a Silverlight Developer is why are there no Triggers in Silverlight?  This question has been answered a few times (one of which is in references below).  Mainly because Silverlight has always had the Visual State Manager (VSM) which is far more powerful than triggers.

Triggers were a great tool for developers in WPF for a while, and were really easy to implement in code. Developers loved them but designers hated them.  Designers had no way of applying easing animations or "softer" transitions rather than just a snap into another state.  In fact now, WPF4 has the VSM as well and combined with Blend 4 the VSM is easy to use and very fast to create different visual representations of a button for default and mouse over and animations in between for example.

If you are starting a new WPF application you would be wise to prefer VSM over triggers.  Even in the most basic state changes, there may be a time when someone will want to add animation or edit it in Blend. Blend doesn't play nicely  with triggers I have found.

I wrote a quick little demo to show how the VSM works and how to use it with the MVVM pattern.

Download the code here.
Screen shots:
You can't see the easing animation in the screenshots obviously, but its there in the code.  There are 2 states for this sample application, there is either an incoming call, or you are on a call.  Depending on the state the button color and text changes.

The challenge with MVVM is that you want the controller to own and control the state.  This is done by the magic of binding to an attached property.
Here's the State property on the controller:

        public CallCardState CurrentState
        {
            get
            {
                return this.currentState;
            }

            private set
            {
                this.currentState = value;
                NotifyPropertyChange("CurrentState");
                NotifyPropertyChange("MainActionLabel");
            }
        }


The return type is a simple custom enum (with 2 possible values).  The MainActionLabel is where the button gets its text from, which in my simple example is using a switch case to return appropriate text.
Here's the Xaml binding for Visual State:

<UserControl 
    x:Class="VSMTest.CallCard" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    d:DesignHeight="200" 
    d:DesignWidth="300" 
    local:VisualStateHelper.VisualStateName="{Binding CurrentState}" 
    mc:Ignorable="d" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:local="clr-namespace:VSMTest" >
...</UserControl>


Here you can see the binding to a custom attached property, this is done at the control level.  In my case the control is the entire panel showing a button on the right and some text on the left. In this example the state applies to the whole user control.

Here's the code for the attached property:

namespace VSMTest
{
    using System;
    using System.Windows;
    using System.Windows.Controls;

    public class VisualStateHelper : DependencyObject
    {
        public static readonly DependencyProperty VisualStateNameProperty = DependencyProperty.RegisterAttached(
            "VisualStateName", 
            typeof(string), 
            typeof(VisualStateHelper), 
            new PropertyMetadata(OnVisualStateNameChanged));

        public static string GetVisualStateName(DependencyObject target)
        {
            return target.GetValue(VisualStateNameProperty).ToString();
        }

        public static void SetVisualStateName(DependencyObject target, string visualStateName)
        {
            // This may throw an exception if an enum is used. However, it shouldn't be used as the user control
            // should not set its own state, the controller will always set it.
            try
            {
                target.SetValue(VisualStateNameProperty, visualStateName);
            } catch (Exception ex)
            {
                throw new NotSupportedException("Setting visual states from within the user control or from binding is not supported. It should be set by the controller", ex);
            }
        }

        private static void OnVisualStateNameChanged(object sender, DependencyPropertyChangedEventArgs args)
        {
            var visualStateName = args.NewValue.ToString();
            var control = sender as Control; // Must be a control, ie an input control.
            if (control == null)
            {
                throw new InvalidOperationException("This attached property only supports types derived from Control (ie UserControl).");
            }

            // Apply the visual state.
            VisualStateManager.GoToState(control, visualStateName, true);
        }
    }
}

The critical piece here is the OnVisualStateNameChanged, this is triggered when the controller changes the underlying value. When it does the VisualStateManager.GoToState static method is called, and the magic begins.


Summary
Using the VSM is even easier if you choose not to use MVVM, but even using MVVM it is pretty straight forward. Even for quick simple applications I find myself regretting using triggers and not using VSM straight off, just like when I think using code behind might be quicker than using MVVM.
It might be a little more code than using triggers but it is definitely more flexible and easier to get right. Designers can use Blend to perfect animations and colours leaving us developers to get the real work done ;-)




References:

Monday, May 24, 2010

WCF Security and RIA Security in general

This is a very lazy post. I just read two really good articles on RIA (Rich Internet Application) Security and Wcf Security.  

My Lead In Intro:
Lets face it when it comes to client-side code (by this I mean anything running in a client's browser, javascript, Silverlight, Flash etc) it running in an insecure zone and you cannot prevent it from being disassembled, examined, and maliciously manipulated.  This boils down to: Its a waste of time trying to write clever security code in these kinds of apps.  Time is better invested in securing your Wcf Services.


PS: As a side bar, I spoke to a Mt Eden developer in January that didn't believe me when I was explaining the simplicity of implementing secure Wcf Services was not possible without considerable effort and code. You know who you are. This has been available since 3.5 service pack 1.

Cheers ;-)

Friday, September 25, 2009

Silverlight3 3D Research

Here's my latest progress with Silverlight 3 3D prototyping.

[Edit - I've taken this off line, but here is a screen shot. I might write something better in SL4 or xbap soon.]


Tuesday, July 28, 2009

Silverlight Client Access Policy

How to consume a WCF service from a Silverlight application, where the WCF service is not hosted in IIS.  When a service is not hosted in IIS you have to serve the client access policy xml file manually to the client.  IIS does this job for you if you're hosting using IIS. (Not sure about WAS would be interested to find out at some point).  

Without serving the client policy xml file you will get a SecurityException. Something along the lines of:
{System.Security.SecurityException ---> System.Security.SecurityException: Security error. 
at MS.Internal.InternalWebRequest.Send() 
at System.Net.BrowserHttpWebRequest.BeginGetResponseImplementation() 
at System.Net.BrowserHttpWebRequest.InternalBeginGetResponse(AsyncCallback callback, Object state) 
at System.Net.AsyncHelper.<>c__DisplayClass4.b__3(Object sendState) --- End of inner exception stack trace --- 
at System.Net.AsyncHelper.BeginOnUI(BeginMethod beginMethod, AsyncCallback callback, Object state) 
at System.Net.BrowserHttpWebRequest.BeginGetResponse(AsyncCallback callback, Object state) 
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteSend(IAsyncResult result) 
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.OnSend(IAsyncResult result)}

Here's a solution:


You need to modify you're WCF service app.config.
    1 <?xml version="1.0" encoding="utf-8" ?>
    2 <configuration>
    3   <system.serviceModel>
    4     <behaviors>
    5       <serviceBehaviors>
    6         <behavior name="enableMetaData" >
    7           <serviceMetadata httpGetEnabled="true" />
    8         </behavior>
    9       </serviceBehaviors>
   10       <endpointBehaviors>
   11         <behavior name="webHttpBehavior">
   12           <webHttp/>
   13         </behavior>
   14       </endpointBehaviors>
   15     </behaviors>
   16     <services>
   17       <service name="SampleNamespace.MyService" behaviorConfiguration="enableMetaData">
   18         <host >
   19           <baseAddresses>
   20             <add baseAddress="net.tcp://localhost:9000"/>
   21             <add baseAddress="http://localhost:9001"/>
   22           </baseAddresses>
   23         </host>
   24         <endpoint address="Calculator" binding="netTcpBinding" contract="SampleNamespace.IMyService" />
   25         <endpoint address="Calculator" binding="basicHttpBinding" contract="SampleNamespace.IMyService" />
   26         <endpoint address="" binding="webHttpBinding" behaviorConfiguration="webHttpBehavior" contract="SampleNamespace.IClientAccessPolicy" />
   27       </service>
   28     </services>
   29   </system.serviceModel>
   30 </configuration>


Add an endpoint to your service for the IClientAccessPolicy. It needs to be Http.  Notice the behaviours are configured to allow http Get.

[ServiceContract]
public interface IClientAccessPolicy
{
    [OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
    Stream GetClientAccessPolicy();
}
...

Add the implementation to the existing service...
public class MyService : IMyService, IClientAccessPolicy
    {
        //Existing code...
 
        public Stream GetClientAccessPolicy()
        {
            const string result = @"<?xml version=""1.0"" encoding=""utf-8""?>
<access-policy>
    <cross-domain-access>
        <policy>
            <allow-from http-request-headers=""*"">
                <domain uri=""*""/>
            </allow-from>
            <grant-to>
                <resource path=""/"" include-subpaths=""true""/>
            </grant-to>
        </policy>
    </cross-domain-access>
</access-policy>";
 
            if (WebOperationContext.Current != null)
                WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
            return new MemoryStream(Encoding.UTF8.GetBytes(result));
        }
    }
Navigating to http://localhost:9001/clientaccesspolicy.xml should give this result in your browser:<?xml version="1.0" encoding="utf-8"?>
<access-policy>
    <cross-domain-access>
        <policy>
            <allow-from http-request-headers="*">
                <domain uri="*"/>
            </allow-from>
            <grant-to>
                <resource path="/" include-subpaths="true"/>
            </grant-to>
        </policy>
    </cross-domain-access>
</access-policy>