Mariano Ravinale's Blog

.Net Experiences

Asp.net MVC Simple CQRS part 3 – Command

leave a comment »

In this part we need to implement a mechanism that will change the state of our domain, this mechanism will be the CommandMessage.

this Command should delivery a message that will change the state of our domain, and our view should reflect that change.

after each commit or domain change, we should trigger a view update, for that reason I thaught that SignalR would be a good fit.

Example:

Command

public interface ICommand { }

public class DeleteAlbumCommand : ICommand
{
	public int Id { get; set; }
}

This command is an action that will be triggered by the user in order to delete an Album

CommandProcessor

public class CommandProcessor : IProcessCommand
{
	private readonly IWindsorContainer container;
	public CommandProcessor(IWindsorContainer container)
	{
		this.container = container;
	}	
	public void Execute(ICommand command)
	{
		dynamic handler = Assembly.GetExecutingAssembly()
					.GetTypes()									
					.Where(t =>typeof(IHandleCommand<>)
					.MakeGenericType(command.GetType()).IsAssignableFrom(t)
					 && !t.IsAbstract
					 && !t.IsInterface)	
					.Select(i => container.Resolve(i)).Single();

		handler.Handle((dynamic)command);
	}
}

Each command needs to be sent to the handler, for that we need a routing mechanism as well,
and that should be the resposability of the command processor.

Abstract CommandHandler:

public abstract class BaseCommandHandler<TCommand> : IHandleCommand<TCommand> where TCommand : ICommand
{
	public ISessionFactory SessionFactory { get; set; }
	public IConnectionManager ConnectionManager { get; set; }

	protected ISession Session
	{
		get { return SessionFactory.GetCurrentSession(); }
	}

	#region Implementation of IHandleCommand<TCommand>
		public abstract void Handle(TCommand command);
	#endregion
}

The BaseCommandHandler will provide the basic infrastructure to handle any business logic
these handlers will cause a change of the states of our domain, each command is particular action
for that will cause a change and after this change we need to alert or syncronize all clients.

CommandHandler


public class DeleteAlbumCommandHandler : BaseCommandHandler<DeleteAlbumCommand> 
{
	public override void Handle(DeleteAlbumCommand command)
	{
		var entity = Session.Get<Core.Album>(command.Id);
		Session.Delete(entity);

		//client side method invocation (update the clients!)
		ConnectionManager.GetClients<AlbumsHub>().Redraw();
	}
}

The mechanism and resposability for synchronize all domain changes will be asigned to SignalR, after each change
SignalR will trigger the redraw event of the datatable plugin, this event will update all the data that is
being displaying in that moment.

Handlers Installer: 

public class HandlersInstaller : IWindsorInstaller
{
	public void Install(IWindsorContainer container, IConfigurationStore store)
	{
      		var metadataProviderContributorsAssemblies = new[] { typeof (QueryProcessor).Assembly };
		container.Register(AllTypes.From(metadataProviderContributorsAssemblies
                                           .SelectMany(a => a.GetExportedTypes()))
                           .Where(t => t.Name.EndsWith("Handler") && t.IsAbstract == false)
                           .Configure(x => x.LifestyleSingleton())
        	);
      		
                container.Register(Component.For<IProcessQuery>()
                         .ImplementedBy<QueryProcessor>().LifeStyle.Singleton);
                container.Register(Component.For<IProcessCommand>()
                         .ImplementedBy<CommandProcessor>().LifeStyle.Singleton);

    	}
}

An example of the registration of our components using Windsor Castle Container.

MvcInstaller: 

 public class MvcInstaller : IWindsorInstaller
{
	public void Install(IWindsorContainer container, IConfigurationStore store)
	{
		container.Register(
			AllTypes.FromAssemblyContaining<HomeController>()
				.BasedOn<IController>()
				.WithService.Self()
				.Configure(cfg => cfg.LifestyleTransient()),
				
			Component.For<IControllerFactory>().ImplementedBy<WindsorControllerFactory>(),
			Component.For<IConnectionManager>().Instance(AspNetHost.DependencyResolver.Resolve<IConnectionManager>())
		
			);

		DependencyResolver.SetResolver(new WindsorDependencyResolver(container));
	}
}

Remeber that be need to register the SignalR components here you have an example of how
to register the IConectionManager.

Asp.Net MVC Controller’s example: 

public class AlbumsController : Controller
{
	public IProcessCommand CommandProcessor { get; set; }
	public ActionResult Index() { return View(); }

	[HttpPost]
	public void Delete(DeleteAlbumCommand command)
	{
		CommandProcessor.Execute(command);
	}
}

In our Controller we need to inject the command Processor, and execute
the delete command that contains the id of the album the we need to delete.

SignalR in Album.js: 

var Albums = (function ($) {
    var public = {};

    public.init = function (param) {
        initSignalR();
        initLayoutResources();
    };

    var initLayoutResources = function () {      
        $(".link").button();       

        $("#dialog").dialog({ autoOpen: false, modal: true });

        $(".edit-link").createForm({ baseUrl: "Albums/Edit/" });
        $(".details-link").createForm({ baseUrl: "Albums/Details/" });
        $(".insert-link").createForm({ baseUrl: "Albums/Insert/" });
        $(".delete-link").deleteAction({ baseUrl: "Albums/Delete/" });
    };

    var initSignalR = function () {
        //Create SignalR object to get communicate with server
        var hub = $.connection.AlbumsHub;

        hub.Redraw = function () {
            DataTable.reload();
        };
        // Start the connection
        $.connection.hub.start();
    };

  return public;

} (jQuery));

Remember that we need to update the state of the clients after each command action that
triggered a domain change, for that we should initialize the SignalR comunication with the server and
declare the redraw function that will call the jQuery Datatable reload method in order to update all the data.

Download or Fork the project on GitHub

May the code be with you!.

Mariano Ravinale

Creative Commons License

Written by @mravinale

octubre 14, 2012 at 9:05 pm

Publicado en Asp.Net MVC

Etiquetado con ,

Asp.net MVC Simple CQRS part 2 – Edit form using jquery dialog

with 2 comments

The goal:

Reuse all Asp.net MVC Form client/server validations functionality using jquery dialog.

This feature will be useful for this post series and for building general crud applications, as well.

Example:

First, let’s create our model:

public class AlbumModel
	{
		[Display(Name = "Id")]
		public int AlbumId { get; set; }

		[Required]
		public string Title { get; set; }

		[HiddenInput(DisplayValue = false)]
		[Display(Name = "Artists")]
		public int ArtistId { get; set; }

		public string ArtistName { get; set; }
		
		public IEnumerable<SelectListItem> Artists { get; set; }
	}

Now, we should create a partial view in order to render the Form

Edit.cshtml:

@model Chinook.Core.AlbumModel

@using (Html.BeginForm("Edit", "Albums",FormMethod.Post, new { id = "EditForm" }))
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Edit Album - @Model.AlbumId</legend>
         @Html.HiddenFor(model => model.AlbumId)
        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ArtistId)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.ArtistId, Model.Artists, new { style = "width: 206px" })
            @Html.ValidationMessageFor(model => model.ArtistId)
        </div>
                <p>
			<input type="submit" value="Save" />
		</p>
    </fieldset>
}

<!--Lets add jquery validations for model Validations before submit-->
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
    $(document).ready(function () {
        $('#EditForm').ajaxForm({
            beforeSubmit: function () {
                return $('#EditForm').valid();
            },
            success: function () {
                $('#dialog').dialog("close");
            }
        });
    });
</script>

As you can see I’ve added jquery.validate.min.js and jquery.validate.unobtrusive.min.js this will executed when
the partial view is loaded after ajax call has been made.

A little peace of functionality must be writen first, two events:
before submit, verify all the fields are valid and
Success, when everything is ok close the dialog.

Album.js

$(function () {
    Albums.init();
});

//Module Pattern: http://tinyurl.com/crdgdzn
var Albums = function () {

  var initLayout = function () {
        $(".edit-link").button();
        $("#dialog").dialog({ autoOpen: false, modal: true });
    };

  var initEditForm = function () {
     $(".edit-link").live('click', function (event) {
        event.preventDefault();
         $.ajax({
             url: "Albums/Edit/1",
             success: function (data) {
                  $("#dialog").html(data);
                 $("#dialog").dialog('open');
             },
             error: function () { alert("Sorry,error"); }
          });
     });
   }
    // Reveal public pointers to
    // private functions and properties
    return {
        init: function () {
            initLayout();
            initEditForm();
        }
    };

} ();

Now in order to call the Form we need to add an ajax call, we should call to the server asking for the information and the html, and add this html to the div with the id “dialog”.

AlbumsController:

[HttpGet]
public ActionResult Edit(GetAlbumsByIdQuery query)
{
    return PartialView("Edit", QueryProcessor.Execute(query));
}

When someone calls to this method we will return the partial view with the information retrieved from the database.

Index.cshtml

<div id="demo">	
	<div>	   
	    <a class="edit-link" href="">Edit Album</a>
	</div>

	<table id="example" class="display" >
		<thead>
			<tr>
			   <th>Id</th>
			   <th>Title</th>
                           <th>Artist Name</th>
			</tr>
		</thead>
		<tbody></tbody>
	</table>
    
    <div id="dialog" title="Basic dialog"></div>
</div>

<script src="@Url.Content("~/Scripts/albums.js")" type="text/javascript"></script>

Finally the index page, here you can see the anchor that will be the trigger for the dialog call.
and the div that will be the container for the html form rendered.

in the next post, we’ll see how to render the data grid using http://datatables.net/ using ajax.

Download or Fork the project on GitHub

May the code be with you!.

Mariano Ravinale

Creative Commons License

Written by @mravinale

septiembre 23, 2012 at 9:04 pm

Publicado en Asp.Net MVC

Asp.net MVC Simple CQRS part 1 – Query

with 5 comments

Inspired by the Jeremy blog post crud its now cqrs or is it and
Gregory Young simple CQRS project: https://github.com/gregoryyoung/m-r

I’ve been working in a very simple insight for Asp.net MVC, in order to work comfortably in our business applications.

Quoting some words of Jeremy Likness: “CQRS provides what I think is a very valuable insight: that how you read and query data is probably very different from how you manage, update, and manipulate data. You don’t have to have a picture-perfect implementation of CQRS to take advantage of this concept”

image

The main Idea is to encapsulate our query and execute it using a processor, the processor wil be in charge to match each query to their handler in order to return the result from the data source.

Let’s take a look inside the code:

Query: Will define an unique query action with an expected result

public interface IQuery { }
public class GetAlbumsByIdQuery : IQuery
{
    public int Id { get; set; }
}

QueryProcessor: Will be in charge to match each query to their handler (using reflection and with a little help of dynamics) returning the handler’s result from the datasource.

public class QueryProcessor : IProcessQuery
{
	private readonly IWindsorContainer container;
	public QueryProcessor(IWindsorContainer container)
    	{
        	this.container = container;
    	}
 	public TResult Execute(IQuery query)
 	{
		 dynamic handler = Assembly.GetExecutingAssembly()
		 	.GetTypes()
			 .Where(t =>typeof(IHandleQuery)
			 .MakeGenericType(query.GetType(), typeof(TResult)).IsAssignableFrom(t)
			 	&& !t.IsAbstract
			 	&& !t.IsInterface)
			 .Select(i => container.Resolve(i)).Single();
		 return handler.Handle((dynamic)query);
 	}
}

Abstract QueryHandler: This abstract class will implement the base signature for each handler that we will create, in order to have NHibernate Infrastructure ready for our queries.

public abstract class BaseQueryHandler : IHandleQuery where TQuery : IQuery
{
	public ISessionFactory SessionFactory { get; set; }
	protected ISession Session
	{
        	get { return SessionFactory.GetCurrentSession(); }
	}
	#region IQueryHandler Members
	public abstract TResult Handle(TQuery query);
	#endregion
}

QueryHandler: Given the query and the returning signature we will execute the query and map the entity to our view Model using Automapper

public class GetAlbumsByIdQueryHandler : BaseQueryHandler
{
	public override AlbumModel Handle(GetAlbumsByIdQuery query)
 	{
 		var entity = Session.Get(query.Id);
		return Mapper.Map(entity);
 	}
}

Windsor Installer: 

public class HandlersInstaller : IWindsorInstaller
{
	public void Install(IWindsorContainer container, IConfigurationStore store)
	{
      		var metadataProviderContributorsAssemblies = new[] { typeof (QueryProcessor).Assembly };
		container.Register(AllTypes.From(metadataProviderContributorsAssemblies
                                           .SelectMany(a => a.GetExportedTypes()))
                           .Where(t => t.Name.EndsWith("Handler") && t.IsAbstract == false)
                           .Configure(x => x.LifestyleSingleton())
        	);
      		
                container.Register(Component.For<IProcessQuery>()
                         .ImplementedBy<QueryProcessor>().LifeStyle.Singleton);
                container.Register(Component.For<IProcessCommand>()
                         .ImplementedBy<CommandProcessor>().LifeStyle.Singleton);

    	}
}

Asp.Net MVC Controller’s example: 

public class AlbumsController : Controller
{
	public IProcessQuery QueryProcessor { get; set; }
	public ActionResult Index() { return View(); }

	[HttpGet]
	public ActionResult Details(GetAlbumsByIdQuery query)
	{
	      return PartialView("Details", QueryProcessor.Execute(query));
    	}
}

Now executing our query we’ll get the result in order to fill our view.

In case you are wondering about how to Handle NHibernate Session in Asp.net Mvc, I would recommend take a look to this post:

http://nhforge.org/blogs/nhibernate/archive/2011/03/03/effective-nhibernate-session-management-for-web-apps.aspx

And of course  read about mapping by code:

http://fabiomaulo.blogspot.com.ar/2011/04/nhibernate-32-mapping-by-code.html

Next post I’ll show the view, and command handling.

Download or Fork the project on GitHub

May the code be with you!.

Mariano Ravinale

Creative Commons License

Written by @mravinale

junio 20, 2012 at 5:48 pm

Publicado en Asp.Net MVC

Visual State Publisher

leave a comment »

The Idea is that when we do doubleClick over the list we’ll see the detail and again doing doubleClick we’ll see the list again.

In this proyect I’ve added some flavor doing some states animations, so in the viewmodel you may see this implementation:

 private ICommand _showDetailCommand;
       public ICommand ShowDetailCommand {
           get {
               if (_showDetailCommand == null) {
                   _showDetailCommand = new RelayCommand<string>(state =>
                       Publisher.VSM.Publish(state)
                   );
               }
               return _showDetailCommand;
           }
       }

       private ICommand _showListCommand;
       public ICommand ShowListCommand {
           get {
               if (_showListCommand == null) {
                   _showListCommand = new RelayCommand<string>(state =>
                        Publisher.VSM.Publish(state)
                   );
               }
               return _showListCommand;
           }
       }

For that we need to implement both commands as you can see and a event publisher implementation for each one, that what really is a Facade that encapsulates a Mediator Pattern implementation that in Mvvm Light is named as Messenger .

 public static class VSM {

           public static void Publish<T>(T message) where T : class {
               Messenger.Default.Send<T>(message, typeof(VSM));
           }

           public static void Register<T>(object reference, Action<T> action) where T : class {
               Messenger.Default.Register<T>(reference, typeof(VSM), action);
           }

            public static void UnRegister<T>(object reference) where T : class {
               Messenger.Default.Unregister<T>(reference);
           }

       }

Ok, but how can I call the View?!??! because the VSM is there!!! there’s a couple solutions for that, but what I really like is to use a behavior, the code is quite reusable and we can attach to any control the code is quite simple:

 public class VSMBehavior : Behavior<FrameworkElement> {

        public VSMBehavior() { }

        protected override void OnAttached() {
            base.OnAttached();

            Publisher.VSM.Register<string>(this, state =>
                VisualStateManager.GoToState(AssociatedObject as Control, state, true)
            );
        }

        protected override void OnDetaching() {
            base.OnDetaching();

            Publisher.VSM.UnRegister<string>(this);
        }
    }

In case you want to see other implementations your are free to see some of them VSM1, VSM2,

But one of the best implementations for MVVM VSM is here the Visual State Aggregator by Jeremy Likness. Based on the Event Agregator Pattern, but is very similar to the Mediator pattern and in Mvvm is already implemented, so I thaught to use it in a similar way.

Ok, but all this really works?

that would be my question if I was reading a post like this, for that reason I’ve made this short video showing the project working:

I really hope this article would be helpful and encorage you to use Ninject Di/Ioc and extensions with Mvvm Light,

Here you can download the project.

The project uses some Data sample provided by Blend, in some future post we can add some real services and some more animations.

Written by @mravinale

febrero 20, 2011 at 12:41 am

Publicado en Uncategorized

Working with MvvmLight and Ninject cool extensions

with one comment

Today I would like to share some cool stuff that you can do with MvvmLight and Ninject extensions,

Other objective of this article is to show how to implement in a very quick way(easy steps) the AOP IANPC Interception (actions to be executed before or after the execution of every call to a method in our code) provided by Ninject Extensions(DI/Ioc) applied in the implementation of the interface INotifyPropertyChange as a simple atribute.

in other words :

We are going to change this code:

      public class SomeViewModel : ViewModelBase {

           private ObservableCollection<Item> _listCollection;
           public ObservableCollection<Item> ListCollection {
               get {
                   return _listCollection;
               }
               set {
                   _listCollection = value;
                   OnPropertyChanged("ListCollection");
               }
           }
       }

To this code:

       public class SomeViewModel : AutoNotifyViewModelBase {

           [NotifyOfChanges]
           public virtual ObservableCollection<Item> ListCollection { get; set; }

       }

A little of history and motivation first:

I’ve been doing some experiments with AOP, and then I saw a really nice article in code project about using Aspects applied to INotifyPropertyChanged (INPC), but I didn’t see a Ninject implementation so as always I’ve started to google about it.

What I saw was a gret article of Jonas Follesoe talking about using dynamic proxy for automatic INPC with Ninject I really recomend to read that post and download the project.

Reading article you can see that Ian Davis, the owner of interseption-extension for Ninject, contacted Jonas, and then he made his own adaptation of automatic INPC(IANPC) another great article

After couple week I had some free time and I wanted to see the source, of Ian davis project, and realised that the code of the IANPC was already inside, so I’ve started to make it work for share with you.

Let’s start to see the implementation:

First step is download the assemblies that we need:

Get Silverlight Ninject asemblies from GitHub.

Get Common Service locator from codeplex.

Ones that we finished to add all references to the project, let’s get to work!

In this example we are going to fill a List(Flick Behavior) with some mock items and add some effects.

Add a new Class named IocContainer.cs

image

Add the binding for each instance that you need in your project, as an example I’ve made some bindings for the main instance that I need to use:

public class IocContainer : NinjectModule {

       public override void Load() {

           this.Bind<ISampleDataSource>().To<SampleDataSource>();   

           //Services
           this.Bind<IDataService>().To<MockItemsService>();            

           //Pages
           this.Bind<MainPage>().ToSelf();

           //ViewModels
           this.Bind<MainViewModel>().ToSelf();

       }
   }

Add the Ioc Initialization into the app, Adding The Bootstrapper

    public class Bootstrapper
    {
        private static IKernel Container { get; set; }

        public static void Initialize()
        {
            Container = new StandardKernel(new DynamicProxy2Module(), new IocContainer());
            ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(Container));
        }

        public static void ShutDown()
        {
            Container.Dispose();
        }
    }

The normal implementation of this would be something like this:

var kernel = new StandardKernel(new IocContainer());

But we need to create proxies in order to do the Interception to our virtual members, that’s way we’ve added the new instance of DynamicProxy2Module, and way we need the reference to Castle.Core assembly.

Let’s do the last and important part of IANPC , the atribute NotifyOfChanges :)

[NotifyOfChanges]

public virtualObservableCollection<Item> ListCollection { get; set; }

But we need to implement the Interface IAutoNotifyPropertyChanged from Ninject.Extensions.Interseption in our view model otherwise it won’t work, but in MvvmLight we have a ViewModelBase with a diferent contract implementation instead to use OnPropertyChanged MvvmLight uses RaisePropertyChanged shit!!, I’ve been forced to create a new class, AutoNotifyViewModelBase that implements IAutoNotifyPropertyChanged and mvvm methods.

Implement the interface IAutoNotifyPropertyChanged in this case is already implmented in AutoNotifyViewModelBase .

public class MainViewModel : AutoNotifyViewModelBase {

      [NotifyOfChanges]
       public virtual ObservableCollection<Item> ListCollection { get; set; }

}

So far we have develop all things required to retrieve data from a service and fill our List Collection, we have the infrastructure using Ninject Ioc, and the interception IANPC Atributes cool right.

May the code be with you!

Mariano Ravinale.

Creative Commons License

This work is licensed under a Creative Commons Attribution 3.0 Unported License

Written by @mravinale

febrero 18, 2011 at 8:15 pm

Publicado en Silverlight

Flick Behavior – Using a SL Listbox control as you do on WP7

with 3 comments

Working with Windows Phone 7, I get used to handle the ListBox control using that flickering efect with my mouse, then I’ve started to seek on the web for some control in Silverlight that imitates the same behavior, and I’ve found the Sasha Barber’s web,  who built a Creating A Scrollable Control Surface In WPF with a nice efect and a very cool way to do the maths and calculate the speed and distance.

So I’ve started to make it work in Silverlight as a user control, the first drop worked, but I made it using a ScrollViewer and ItemsControl, as this example:

<Grid x:Name=”LayoutRoot”>
<
ScrollViewer x:Name=”MyScrollViewer”Margin=”0″Background=”White”

            HorizontalScrollBarVisibility="Disabled">

            <ItemsControl x:Name="itemsControl"
                MouseLeftButtonDown="itemsControl_MouseLeftButtonDown"
                MouseLeftButtonUp="itemsControl_MouseLeftButtonUp"
                MouseMove="itemsControl_MouseMove"
                ItemTemplate="{StaticResource ItemTemplate}"
                ItemsSource="{Binding DataSource, ElementName=userControl}" />

        </ScrollViewer>
</Grid>

but I didn’t like it, because the listbox it is more popular, and it has already a ScrollViewer and the ItemsPresenter as a Template, but it was ok, so far I’ve learned that the key is handle the MouseLeftbuttonDown , MouseLeftButtonUp and Mousemove events, to do the Maths.

So now what I’ve got to do is create a behavior for the ListBox, navigate inside the template, and get attached to the events mentionated before.

yap,but how can I find the ItemsPresenter within the ListBox?,the answer would be with the findByType<T> method, inspired by the XamlQuery library, with some magic to make it portable ;)

protected IEnumerable<DependencyObject> FindByType<T>(DependencyObject control) where T : class {
  var childrenCount = VisualTreeHelper.GetChildrenCount(control);
  for (var index = 0; index < childrenCount; index++) {
      var child = VisualTreeHelper.GetChild(control, index);
      if (child is T) yield return child;
      foreach (var desc inFindByType<T>(child)) {
        if (desc is T) yield return desc;
      }
  }
}

And now let’s find the scrollViewer and the ItemsPresenter inside the ListBox.

MyScrollViewer = FindByType<ScrollViewer>(AssociatedObject).ToList().First() as ScrollViewer;
MyItemPresenter = FindByType<ItemsPresenter>(AssociatedObject).ToList().First() as ItemsPresenter;

Yea!, so far so good, now I’ve got the main controls for the LisBox, and now let’s try to do the same that I did with the user control. but the problem was that the MouseLeftButtonDown didn’t work beacuse the event was toked by it’s parent in this case Listbox for the  SelectionChanged event so the trick is to add handlers:

MyItemPresenter.AddHandler(UIElement.MouseLeftButtonDownEvent,
                           new MouseButtonEventHandler(ItemPresenter_MouseLeftButtonDown), true);
MyItemPresenter.AddHandler(UIElement.MouseLeftButtonUpEvent,
                           new MouseButtonEventHandler(ItemPresenter_MouseLeftButtonUp), true);

Ok, now lets handle the events: first let’s track the mouse position, and calculate the desviation between the last point that it has been captured, and the current,so the follow event will be in charge of that:

private void AssociatedObject_MouseMove(object sender, MouseEventArgs e) {

   if (IsMouseCaptured ) {
      CurrentPoint = new Point(e.GetPosition(AssociatedObject).X,
                               e.GetPosition(AssociatedObject).Y);
      var delta = new Point(ScrollStartPoint.X - CurrentPoint.X,
                            ScrollStartPoint.Y - CurrentPoint.Y);

      ScrollTarget.X = ScrollStartOffset.X + delta.X / Speed;
      ScrollTarget.Y = ScrollStartOffset.Y + delta.Y / Speed;

      MyScrollViewer.ScrollToHorizontalOffset(ScrollTarget.X);
      MyScrollViewer.ScrollToVerticalOffset(ScrollTarget.Y);
  }

And now let’s take a look to the events in charge to do the capture of the mouse clicks and points:

private void ItemPresenter_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {

    ScrollStartPoint = new Point(e.GetPosition(AssociatedObject).X,
                                 e.GetPosition(AssociatedObject).Y);
    ScrollStartOffset.X = MyScrollViewer.HorizontalOffset;
    ScrollStartOffset.Y = MyScrollViewer.VerticalOffset;

    IsMouseCaptured = !IsMouseCaptured;

}

private void ItemPresenter_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {

    IsMouseCaptured = !IsMouseCaptured;
}

Take a look to this video Introducing the behavior.

if you are interested to see how it works take a look to this video

remember to visit Michael’s page for see how to create sample datasource  http://geekswithblogs.net/mbcrump/archive/2010/09/03/easy-way-to-generate-sample-data-for-your-silverlight-4.aspx

you’re free to grab the code and see how it was built, whith this post I’ve tried to share with you the journey making this component, and I really hope, that you may find this control useful and you may improve it for your own needs.

See it in action and download In expression Blend Gallery!

may the code be with you.

Mariano Ravinale

Creative Commons License

This work is licensed under a Creative Commons Attribution 3.0 Unported License

Written by @mravinale

noviembre 14, 2010 at 2:40 am

Publicado en Silverlight

Mvvm Light project template for Windows Phone 7 RTM

with 2 comments

Today I would like to share a project template ready to build great windows phone 7 applications using Mvvm Light, first of all this this project template is an update that I made from the current Mvvm Light project hosted on codeplex: http://mvvmlight.codeplex.com/ my favorite toolkit to build Silverlight and Windows Phone 7 applications.

Besides to make it compatible for the current tools version, and support the Laurent Bugnion Project, I just added a very simple reactive extensions example, in order to make it ready to work with services in our model.

Download the file: MvvmLight WP7 RTM

remember to paste the .zip on project templates folder.

Example:

C:\Users\Mariano\Documents\Visual Studio 2010\Templates\ProjectTemplates\Silverlight for Window Phone\Mvvm

I hope this could be Helpful.

May the code be with you.

Mariano Ravinale.

Creative Commons License

This work is licensed under a Creative Commons Attribution 3.0 Unported License

Written by @mravinale

octubre 27, 2010 at 10:01 pm

Publicado en Windows Phone 7

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.