(X) Hide this
    • Login
    • Join
      • Generate New Image
        By clicking 'Register' you accept the terms of use .

Developing Silverlight Analog Clock - pattern oriented approach

(70 votes)
Pencho Popadiyn
>
Pencho Popadiyn
Joined Apr 30, 2008
Articles:   22
Comments:   97
More Articles
30 comments   /   posted on Oct 30, 2008

This article is compatible with the latest version of Silverlight.

1. Introduction

I have been trying to get myself up to speed with the latest Microsoft technologies and more specially .NET 4,VS.NET 2008 and Silverlight/WPF. So rather than just ‘playing’ I have set myself a little application to write: a simple analog Silverlight clock.

It is extremely simple application that I have been able to complete the first version of it just for few days (working only in my spare time, if I had any). The target of that article is to introduce some basic concepts of programming in Silverlight, such as: drawing simple elements, using styles, making simple transformation, as well as introducing some of the most important and powerful approaches in object oriented programming.

 Source code

2. Application Design

 

Before starting to implement my application I had some ideas in my mind for future development and growth of the application, so I decided to make a solid base - appropriate time to practice my OOP skills. After careful consideration I chose to separate my business logic from the user interface. Thus, in future I will be able to easily extend the application, without making any unnecessary changes. There are lots of well-known approaches and one of them is the classical Model – View – Presenter (MVP).

 

2.1 Introducing the Model - View - Presenter (MVP) pattern

There are tons of articles in the Internet about MVP. So, my target is not to reinvent the wheel but to represent the pattern in my words, to represent it in a way I understand it.

The MVP pattern is an OOP pattern which separates the User Interface (the view) from the business logic (the model). The pattern separates the responsibilities across four components, each one has only one responsibility, thus confirming the most basic principle of Single Responsibility (SRP) – ‘A class should have only one reason to change’. The SRP principle is one of the simples of the principles but one of the most difficult to get right. Conjoining responsibilities is something that we do naturally. Finding and separating those responsibilities is much of what software design is really about. That’s why the main target of MVP is confirming the Single – Responsibility principle.

  • The view is responsible only for rendering the UI elements
  • The model is responsible for business behaviors and state management
  • The presenter is responsible for interacting between the view and the model
  • The view interface is used to loosely couple the presenter from its view

The common workflow of the pattern is shown on the next diagram.

The user interacts with the User Interface. One makes an action and as a result the view fires events. The presenter handles them and updates the model.

When the model is updated, the view also has to be updated to reflect the changes. View updates can be handled in several ways. The Model – View – Presenters variants, Passive View and Supervising Controller, specify different approaches to implement view updates. For my application I have been using the first one. What are the differences?

In Passive View, the presenter updates the view to reflect changes in the model. The interaction with the model is handled exclusively by the presenter; the view is not aware of changes in the model.

In Supervising Controller, the view interacts directly with the model to perform simple data – binding that can be defined declaratively, without presenter intervention. 

The next figure illustrates the logical view of the Passive View and Supervising Controller variants.

 

The key benefits of the MVP are obvious:

  • Loose Coupling – the presenter is intermediary between the view and the model
  • Clear separation of responsibilities (confirming the SRP principle)
  • Code reuse – separation of the view and model will increase the code reusability. In fact that is the main target (the heart) of object oriented programming
  • Flexibility and extendibility – your code is more adaptable to changes

The key drawbacks are:

  • Additional complexity. The MVP pattern is not applicable for small applications
  • Entering event driven programming

Without appropriate design often the presenter becomes too complex

 

2.2 Silverlight Clock Design

The basic design of our clock is shown on the next figure.

2.2.1 Clock Model

First I will start with making one class and one interface – ClockData and IClockModel. Both types are in fact the hearts of the model component in the MVP pattern.

The ClockData class is used to transfer data from the model to the presenter and respectively to the view. The class diagram for the ClockData class can be shown on the next figure.

Note: For those who plan to use the ClockData object for data binding must implement the INotifyPropertyChanged interface.

The IClockModel is the interface for our model. In the classical aspect of the MVP pattern there is no additional interface which the model must implement, but in the future I plan to extend my application to something like stopwatch or countdown timer. So that part of the program will suffer frequent changes from now on, and it is better to depend on abstraction rather than on details.

public interface IClockModel
{
    event EventHandler<ClockDataEventArgs> ClockChanging;
    event EventHandler<ClockDataEventArgs> ClockChanged;
 
    void SetClockInterval( TimeSpan timeSpan );
    IClockModel Start();
    IClockModel Continue();
    IClockModel Stop();
    ClockData ClockData { get; set;  }
    bool IsRunning { get; }
}

 

2.2.2 Clock View

 

As I already mentioned, the main target of the view interface is to loosely couple the presenter from its view. The interface design is shown on the next figure. It contains one method which responsibility is to update view. In our application I chose to use the passive view variation of the MVP, so the presenter must be responsible to update the view. That’s why I exposed in the interface the method Update whose exact objective is to update the view.

As you can guess the exposed events are absolutely useless yet, but in the future they will come into play.

 

 2.2.3 Clock Presenter

The only responsibility of the presenter is to be a mediator between the view and the model. Its structure is shown on the next figure.

3. Application Implementation

Each clock and each one of its element is a graphical object. So we can use a grid for top layout root.

<Grid x:Name="LayoutRoot" Background="White">
    <!-- ClockFace -->
    <!-- Markers -->
    <!-- Hands -->
</Grid>

3.1 Drawing the Clock Face

First, I will start with the clock background. I want a circle with a graded fill from top to bottom. I also want our clock to have a nice border for better feeling.

<Canvas x:Name="ClockFaceCanvas" Width="200" Height="200">
 
    <Ellipse x:Name="ClockFaceEllipse" Style="{StaticResource ClockFace}" 
        Canvas.Left="0" Canvas.Top="0" Width="200" Height="200">
    </Ellipse>
 
 </Canvas>

Where the ClockFace is a style defined in the App.xaml file:

<Style x:Key="ClockFace" TargetType="Ellipse">
        <Setter Property="StrokeThickness" Value="6"/>
 
        <Setter Property="Fill">
            <Setter.Value>
                <LinearGradientBrush>
                    <GradientStop Offset="0.0" Color="Black"/>
                    <GradientStop Offset="1.0" Color="White"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
        <Setter Property="Stroke">
            <Setter.Value>
                <LinearGradientBrush>
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0.0" Color="White" />
                        <GradientStop Offset="1.0" Color="Black" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>

So we now have:

 

That is the easy bit done. Markers are the next.

3.2 Drawing the Clock Markers

There are two possible approaches for drawing the clock markers. The first one is to use the main idea of Silverlight/WPF: to include the graphical elements in the XAML, for the little markers around the edge that would be silly – dozens of nearly identical elements says “loop” to me and for that we need to code them. First I will define an additional canvas which will be the root of the markers:

<Canvas x:Name="MarkerCanvas" Width="200" Height="200"/>

Next, lets draw them programmatically. In fact, the markers are just rectangles; to position them I just put them at the top – center of the canvas and rotate around the center.

private void DrawMarkers()
{
    MarkerCanvas.Children.Clear();
 
    for ( int i = 0; i < 60; ++i )
    {
        Rectangle markerRectangle = new Rectangle();
 
        if ( i % 5 == 0 )
        {
            markerRectangle.Width = 3;
            markerRectangle.Height = 8;
            markerRectangle.Fill = new SolidColorBrush( Colors.White );
            markerRectangle.RenderTransform = this.CreateTransformGroup( i * 6,
                -( markerRectangle.Width / 2 ),
                -( markerRectangle.Height * 2 + 4.5 - ClockFaceEllipse.StrokeThickness / 2 - this.clockHeight / 2 ) );
        }
        else
        {
            markerRectangle.Width = 1;
            markerRectangle.Height = 4;
            markerRectangle.Fill = new SolidColorBrush( Colors.White );
 
            markerRectangle.RenderTransform = this.CreateTransformGroup( i * 6,
                -( markerRectangle.Width / 2 ),
                -( markerRectangle.Height * 2 + 12.75 - ClockFaceEllipse.StrokeThickness / 2 - this.clockHeight / 2 ) );
        }
 
        MarkerCanvas.Children.Add( markerRectangle );
    }
}

The CreateTransformGroup method is a help function that creates a transform group for each marker based on the angle that each marker must use to rotate them around the clock center.

private TransformGroup CreateTransformGroup( double angle, double firstTranslateXValue,
                                             double firstTranslateYValue )
{
    TransformGroup transformGroup = new TransformGroup();
 
    TranslateTransform firstTranslate = new TranslateTransform();
    firstTranslate.X = firstTranslateXValue;
    firstTranslate.Y = firstTranslateYValue;
    transformGroup.Children.Add( firstTranslate );
 
    RotateTransform rotateTransform = new RotateTransform();
    rotateTransform.Angle = angle;
    transformGroup.Children.Add( rotateTransform );
 
    TranslateTransform secondTranslate = new TranslateTransform();
    secondTranslate.X = this.clockWidth / 2;
    secondTranslate.Y = this.clockHeight / 2;
    transformGroup.Children.Add( secondTranslate );
 
    return transformGroup;
}

Now we have the basic background.

As you can see, everything which can be done in the XAML, can also be done with procedural code.

3.3 Drawing the Clock Hands

Next we should draw the clock hands. Each hand is a rectangle rounded off a little on the corners. Again two approaches come to my mind. The first is the tricky one: just to draw the clock hands in the XAML and bind the Angle property of their RotateTransform property element to a custom property in my business object. The reason I didn't use that approach is explained in the conclusion.The classical solution is just to draw the hands with procedural code:

<Canvas x:Name="ClockHandsCanvas" Width="200" Height="200"/>
private void DrawSecondsHand( ClockData clockData )
{
    if ( secondsHand != null && ClockHandsCanvas.Children.Contains( secondsHand ) )
        ClockHandsCanvas.Children.Remove( secondsHand );
 
    secondsHand = this.CreateHand( this.secondsHandWidth, this.secondsHandHeight,
        new SolidColorBrush( Colors.Black ), 0, 0, 0, null );
    secondsHand.RenderTransform = this.CreateTransformGroup(
        clockData.Seconds * 6,
        -this.secondsHandWidth / 2,
        -this.secondsHandHeight + 4.25 );
 
    if ( ClockHandsCanvas.Children.Contains( secondsHand ) == false )
        ClockHandsCanvas.Children.Add( secondsHand );
}

The other two functions for drawing the Minute and Hour hands are absolutely equivalent. And the result is:

3.4 Implementing the View

Our analog clock must implement the IView interface which offers one method and several events. The only thing that method must do is just to redraw the clock hands:

public void Update( ClockData clockData )
{
    this.DrawSecondsHand( clockData );
    this.DrawMinutesHand( clockData );
    this.DrawHoursHand( clockData );
}

3.5 Implementing the Model

The clock model must implement the IClockModel interface. For better convenience I have created a base abstract class named ClockBase:

public abstract class ClockBase : IClockModel
{
    private ClockData clockData;
    protected bool isRunning;
    protected DispatcherTimer timer;
 
    public event EventHandler<ClockDataEventArgs> ClockChanging;
    public event EventHandler<ClockDataEventArgs> ClockChanged;
 
    public ClockBase()
    {
        clockData = new ClockData();
        timer = new DispatcherTimer();
        timer.Tick += new EventHandler( timer_Tick );
        this.SetClockInterval( new TimeSpan( 0, 0, 0, 0, 1 ) );
    }
 
    public virtual void SetClockInterval( TimeSpan timeSpan )
    {
        timer.Interval = timeSpan;
    }
 
    public ClockData ClockData
    {
        get
        {
            return this.clockData;
        }
        set
        {
            this.OnClockChangind( new ClockDataEventArgs( this.clockData ) );
 
            this.clockData = value;
 
            this.OnClockChanged( new ClockDataEventArgs( this.clockData ) );
        }
    }
 
    public bool IsRunning
    {
        get
        {
            return this.isRunning;
        }
    }
 
    public abstract IClockModel Start();
    public abstract IClockModel Stop();
    public abstract IClockModel Continue();
    protected abstract void UpdateClockData( DateTime dateTime );
 
    protected virtual void OnClockChangind( ClockDataEventArgs e )
    {
        EventHandler<ClockDataEventArgs> temp = this.ClockChanging;
        if ( temp != null )
            temp( this, e );
    }
 
    protected virtual void OnClockChanged( ClockDataEventArgs e )
    {
        EventHandler<ClockDataEventArgs> temp = this.ClockChanged;
        if ( temp != null )
            temp( this, e );
    }
 
    private void timer_Tick( object sender, EventArgs e )
    {
        this.OnClockChangind( new ClockDataEventArgs( this.ClockData ) );
 
        this.UpdateClockData( DateTime.Now );
 
        this.OnClockChanged( new ClockDataEventArgs( this.ClockData ) );
    }

The ClockModel class inherits the abstract base class and overrides the needed methods.

public class Clock : ClockBase
{
    public static IClockModel Create()
    {
        return new Clock();
    }
 
    public override IClockModel Start()
    {
        if ( IsRunning )
            return this;
 
        timer.Start();
        isRunning = true;
 
        return this;
    }
 
    public override IClockModel Stop()
    {
        timer.Stop();
        isRunning = false;
 
        return this;
    }
 
    public override IClockModel Continue()
    {
        return this.Start();
    }
 
    protected override void UpdateClockData( DateTime dateTime )
    {
        this.ClockData.Update( dateTime );
    }
}

3.6 Implementing the Presenter

The key point of out presenter are:

  • It has references to the View and the Model. It is responsible for handling the events from the View and updating the Model.
  • The callback is just a method. The purpose of the delegate mechanism is to chain the Update method of the View.
public class ClockPresenter
{
    public Callback Response;
 
    public ClockPresenter( IClockView clockView, IClockModel clockModel )
    {
        this.ClockView = clockView;
        this.ClockModel = clockModel;
        
        this.ClockView.StartClock += new EventHandler( ClockView_StartClock );
        this.ClockView.StopClock += new EventHandler( ClockView_StopClock );
 
        this.ClockModel.ClockChanged += new EventHandler<ClockDataEventArgs>( ClockModel_ClockChanged );
    }
 
    public IClockView ClockView
    {
        get;
        set;
    }
    public IClockModel ClockModel
    {
        get;
        set;
    }
 
    private void ClockView_StopClock( object sender, EventArgs e )
    {
        this.ClockModel.Stop();
    }
 
    private void ClockView_StartClock( object sender, EventArgs e )
    {
        this.ClockModel.Start();
    }
 
    private void ClockModel_ClockChanged( object sender, ClockDataEventArgs e )
    {
        Callback temp = this.Response;
        if ( temp != null )
            temp( e.ClockData );
    }
}

3.7 Testing the Application

IClockModel clockModel = Clock.Create();
clockModel.ClockData = new ClockData().Update( DateTime.Now );
 
ClockPresenter presenter = new ClockPresenter( this.AnalogClockControl, clockModel );
presenter.Response += new Callback( this.AnalogClockControl.Update );
 
clockModel.Start();

4. Conclusion

4.1 Why not using the power of data binding?

The initial idea when start creating my first real Silverlight project was to draw all objects through the XAML, and to use procedural code for my business logic. The general purpose of XAML is a declarative programming language suitable for constructing .NET user interface, isn’t it?

Everything was perfect till the moment when I decided that the ClockData object should implement the INotifyPropertyChanged interface and to use something like this in XAML:

<Rectangle Width="8" Height="36" Fill="White" RadiusX="2" RadiusY="2">
            
    <Rectangle.RenderTransform>
        <TransformGroup>
            <RotateTransform Angle="{Binding Seconds}"/>
        </TransformGroup>
    </Rectangle.RenderTransform>
        
</Rectangle>

When I started the application, an error occurred. After a serious investigation that took me few hours, I found the answer - Silverlight is not allowed to bind to an object which is not a FrameworkElement. While in WPF this is allowed. I think that is a lame limitation and it is too strange for me.


Subscribe

Comments

  • davidjjon

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by davidjjon on Oct 30, 2008 10:33
    Very well done - thank you for sharing this.
     
    David Roh
  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Rajesh Lal on Oct 30, 2008 10:46

     awesome article keep up

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Dave on Nov 04, 2008 20:25

    Really well done article - thanks!

  • ppopadiyn

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by ppopadiyn on Nov 05, 2008 00:25

    Hello guys

    Thanks for the nice words. That was my first real Silverlight project and i was worried about the result. I will keep working harder and plan soon to post a second article about the clock with some improvments and also another patern oriented article with a practicle example. If you have any suggestions about future articles, do not hesitate to share them with me as comments, thanks again for the nice words.

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Naveen on Nov 05, 2008 00:34

    Hi this is Naveen...Excellent!!! Gud Job....keep posting such articles...really usefull for ppl like me who are new this Light.

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Mina Saad on Nov 05, 2008 03:39

    very cool illustrating application and very organized topic , keep Going

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Tom Kinser on Nov 05, 2008 11:58

    Excellent example!  It is direct and concise.  I am a trainer and would love to use this as an example of how MVP and XAML should be done.   Please keep writing...

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Bill Sithiro on Nov 05, 2008 13:52

    With all due respect to your article (I think it's a very good MVC induction) but in the particular context you're using it, I think it’s overkill! I know you're just experimenting but it's important for new developers reading this to also understand when it's a good idea to use a particular OOP pattern and when it's not. In your analog clock example, this should simply be a reusable control with styling/templating capabilities for designers to play with (background, hands etc.) or even throw in a project themselves. This at least is the Silverlight way. Any extensions to the clock like stopwatches as you mentioned are nothing more than subclasses of the clock control. But I’m sounding a little too criticizing and that’s not my intention, just my personal thought... Keep it up!

    Bill Sithiro

  • ppopadiyn

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by ppopadiyn on Nov 05, 2008 15:28

    Hi Bill

    Thanks for the comment. The initial idea of the article was introducing the MVP pattern, and the clock is just a simple example, a concrete realization of the MVP. Of course I agree in the real world using MVP or MVC for simple applications is not appropriate and as you said it is an overkill. This leads to needless complexity - a symptom, which frequently happen when developers anticipate changes to the requirements and put facilities in the software to deal with those potential changes. Preparing for future changes should keep our code flexible and prevent nightmarish changes later. Unfortunately sometimes the effect is not what we expect. By preparing for many contingencies, the design becomes littered with constructs that are never used. Some of those preparation may pay off, but many do not. Also that the design carries the weight of these unused elements. All these make the software difficult for understand and complex.

    But for advance solutions using that pattern can have great benefits. Really I didn't mention when to use the MVP and when not to use it. I think it is a matter of experience. Everyone should experiment with it.

    I will give you a simple example from my experience. Currently I am a part of a team working over a WinForms application for customers from Holland. A very small module of the application was initially intended only for create, read, update and delete data operations (also known as CRUD - a major part of nearly all computer software). That part has been developed before I join to the team and was based on the classical approach - using DataSet, BindingSource, DataRowView, DataBinding.... etc. Everything was perfect until the last 2 months when numerous issues about that module was coming from the clients. All of the issues included implementation of a custom domain logic. I started resolving them one by one mixing the bussiness logic with the user interface (attaching events, adding validation, some calculations....). Suddenly I was faced in a situation where I was asked to make what appears to be a simple change. I looked the change over and made a reasonable estimate. But later when started implementing the change, I found myself chasing changes through huge portions of code, modifying far more functions and classes. Of course the result was "It was too complicated than I thought". After some sleepless nights changing the whole module, removing all bindings and implementing the MVP pattern, my life now is little more easier :)

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Andi X on Nov 06, 2008 02:08

    That's

  • ppopadiyn

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by ppopadiyn on Nov 06, 2008 02:55

    Hi Tom

    Thank you for the nice words. I am very happy you find my article useful. If you have any ideas or wishes for future pattern oriented articles, do not hesitate to share them with me. :)

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by paulo_fg@hotmail.com on Nov 06, 2008 07:23

    why i cant view this in linux?

  • ppopadiyn

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by ppopadiyn on Nov 06, 2008 09:22

    Hi paulo_fg@hotmail.com

    It is not possible to see the current application under Linux. In order to see it you should install Moonlight and to build the sample for Moonlight. Moonlight is an open source implementation of Silverlight, primarily for Linux and other Unix/X11 based operating systems.

    In September of 2007, Microsoft and Novell announced a technical collaboration that includes access to Microsoft's test suites for Silverlight and the distribution of a Media Pack for Linux users. The main goals of that collaboration are:

    • To run Silverlight applications on Linux.
    • To provide a Linux SDK to build Silverlight applications.

    I am not a Linux fan and I am not capable to give you more specific information how to do that.

  • -_-

    COOL


    posted by David on Nov 12, 2008 14:05

    THATS SIMPLY AMAZING, GOOD ARTICLE, I WANNA BE AS U!!!

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Miquel Salvà on Nov 19, 2008 14:57

    Hi!

    First of all thanks for the post it was the best sample about the M-V-P pattern that i found over the net. But i have a doubt about it.

    I would like to know why in the presenter class, a delegate is used to answer to the model changes (instead of using directly this.ClockView.Update(e.ClockData) ) and why a direct acces to the model.Start() (instead of using a delegate) is used to anwer the view changes.

     

    Is it just to show us both ways or it has a real meaning that i am missing?

    Thanks again for everything

  • ppopadiyn

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by ppopadiyn on Nov 19, 2008 15:27

    Hi Miquel

    I am happy that you find the article useful. About your question, there isn't any secret meaning that you are missing. In the classical form of the M-V-P pattern the situation is exactly the same as you have described. The presenter update the view directly (without using delegate), and also the presenter must be attached to the Start event of the IView interface and when the event fires then he calls model.Start(). I can't remember for any valid reason that has forced me to use that approach, maybe just for experiment.

  • Miki

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Miki on Nov 19, 2008 15:36

    Hi!

    First of all thanks for the post it was the best sample about the M-V-P pattern that i found over the net. But i have a doubt about it.

    I would like to know why in the presenter class, a delegate is used to answer to the model changes (instead of using directly this.ClockView.Update(e.ClockData) ) and why a direct acces to the model.Start() (instead of using a delegate) is used to anwer the view changes.

     

    Is it just to show us both ways or it has a real meaning that i am missing?

    Thanks again for everything

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Simon on Feb 13, 2009 01:07

    Why use rar ? why not zip ... then we can all unzip for free ....

  • ppopadiyn

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by ppopadiyn on Feb 13, 2009 02:40

     Hi Simon,

    Sorry for the inconvenience, I will replace the rar archive with zip

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by blueling on Feb 22, 2009 15:16

    > Silverlight is not allowed to bind to an object which is not a FrameworkElement. While in WPF this is allowed. I think that is a lame limitation and it is too strange for me.

    I have just gone through the same experience as you ... there are so many data binding things that do work in WPF that do not in Silverlight.. either the browser crashes or you get "Attribute {StaticResource xyz} value is out of range"...

    That data binding does not work on anything than FrameworkElement is an absolute catastrophe for Silverlight. How fine would it have been to create things like the clock minute markes with a ListBox that uses a Canvas as ItemsPanel and TranslateTransform and RotateTransform to place the bars ... binding to a list of 60 doubles.

    I really hope the next Silverlight version will allow a broader usage of data binding. Also it is a pitty that they did not come up with something like x:Array .. most of the collection classes that ship with the SL framework are Generics which cannot be instanciated in a ResourceDictionary in XAML...

    Excellent article btw... like the even better looking clock from your other post also very much!

  • ppopadiyn

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by ppopadiyn on Feb 24, 2009 00:47

     Hi Blueling,

    First I would like to thank you for the nice words. Yes, sometimes I am very frustrated with the lack of functionality in Silverlight. Looking for "work-arounds" is a very common task when developing Silverlight application. But I think this is normal, however Silverlight is only second version and it is at the beginning of its development. I think we have a wrong practice to compare Silverlight with WPF. I am sure the next version of Silverlight will be much better, and I lot of the problems will be solved.

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by pashute on Jul 22, 2009 16:59
    I wonder if anyone at Microsoft read your concluding comment...  They are advertising this article on the sliverlight blog!
  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Divyesh Sharma on Nov 14, 2009 21:33
    Nice article and fresh use of code. It has given me a new direction of light in silverlight as i was in dark about this topic
  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Sergey on Nov 18, 2009 23:58

    Hi Pencho!

    Thank you for good explanation of MVP pattern. It's clear but situation is changed when an application has more than one Views and Models, then Presenter becomes too complicated. I've never used MVP but I've tried to use MVC and I think they have much in common with each other. But finally, when the Controller became too complex, I decided to reconstruct my application with MVVM pattern and I'm still happy along with it. May be I've left out something and MVC/MVP are good enough too, but I'm still a naive designer and I'm learning by making mistakes. And I haven’t read your other articles about patterns – may be I’ll change my mind.

    Anyway I've translated you article for silverlight.su for Russian as well as some of your other articles because I hope it'll be useful for others and I hope you won't mind.

    I have a question: why you allow “set” mutator in this code:

    public ClockData ClockData
    {
          get
          {
                return this.clockData;
          }
          set
          {
                this.OnClockChangind( new ClockDataEventArgs( this.clockData ) );

                this.clockData = value;

                this.OnClockChanged( new ClockDataEventArgs( this.clockData ) );
          }
    }

    I think it is not a good idea because you use OnClockChaning and OnClockChanged methods in two placed. So you could delete mutator and use:

    clockModel.ClockData.Update( DateTime.Now );
    instead of:
    clockModel.ClockData = new ClockData().Update( DateTime.Now );

    ---------

    Regards, Sergey

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Sergey on Nov 20, 2009 23:18

    > Silverlight is not allowed to bind to an object which is not a FrameworkElement. While in WPF this is allowed. I think that is a lame limitation and it is too strange for me. 

    There some changes in data binding in Silverlight 4 beta documentation:

    The target can be any DependencyProperty of a FrameworkElement. The target can also be a DependencyProperty of a DependencyObject in the following cases:

    • The DependencyObject is the value of a property of a FrameworkElement.

    • The DependencyObject is in a collection that is the value of a FrameworkElement property (for example, the Resources property).

    • The DependencyObject is in a DependencyObjectCollection(T).

     


  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Chris on Nov 29, 2009 22:47
    Hi,

    This is very nice. 

    Could you describe how to handle GUI events, such as Button clicks?  

    Thanks 

    Chris. 


  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Saranyan Yethirajam on Mar 08, 2010 08:06
    Awesome article
  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Piyush Sheth on Jun 15, 2010 21:43

    Really good one !!!

    open my wing towards silverlight.

  • -_-

    RE: Developing Silverlight Analog Clock - pattern oriented approach


    posted by Maurice Calvert on Aug 04, 2010 14:41

    Refreshingly well written. Many thanks.

  • nevin

    Re: Developing Silverlight Analog Clock - pattern oriented approach


    posted by nevin on Apr 13, 2012 12:36

    MERHA.. ÇOK GÜZEL..

Add Comment

Login to comment:
  *      *       

From this series