96
Sviluppare un'app per Sviluppare un'app per WP7 in TDD? Si può fare! WP7 in TDD? Si può fare!

Developing application for Windows Phone 7 in TDD

Embed Size (px)

DESCRIPTION

A real example of how to develop an application for Windows Phone 7 with Test Driven Development approach. In this presentation you'll see also hoew to implements the Model-View-ViewModel (MVVM) pattern.

Citation preview

Page 1: Developing application for Windows Phone 7 in TDD

Sviluppare un'app per WP7 Sviluppare un'app per WP7 in TDD? Si può fare!in TDD? Si può fare!

Page 2: Developing application for Windows Phone 7 in TDD

Who am I?Who am I?• Developer freelance:

– C# Asp.net Mvc, Wpf, Wp7– Python Django– Blog: orangecode.it/blog

• WEBdeBS founder

Page 3: Developing application for Windows Phone 7 in TDD

What we’re going to seeWhat we’re going to see

• TDD• MVVM• Code..• Code…• …some more code!

Page 4: Developing application for Windows Phone 7 in TDD

The show caseThe show case

• Basic application• Download user songs list from

SoundCloud.com• Display the list • View song’s detail

Page 5: Developing application for Windows Phone 7 in TDD

Screen ShotScreen Shot

Page 6: Developing application for Windows Phone 7 in TDD

Let’s do it with code behindLet’s do it with code behind

Page 7: Developing application for Windows Phone 7 in TDD

TrackTrack

public class Track{ public int Id{get; set; } public string Kind { get; set; } public string Title { get; set; } public string Description { get; set; } public string Artwork_url { get; set; } public string Created_at { get; set; }}

Page 8: Developing application for Windows Phone 7 in TDD

XamlXaml<phone:PhoneApplicationPage >

<Grid x:Name="ContentPanel”><Grid.RowDefinitions>

<RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions>

<StackPanel Orientation="Horizontal"><TextBox x:Name="searchedText" /><Button Content="Search"

Click="Search" /></StackPanel>

Page 9: Developing application for Windows Phone 7 in TDD

XamlXaml <ItemsControl Grid.Row="1” x:Name="songsList"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image Source="{Binding Image}" />

<TextBlock Text="{Binding Title}"/> </StackPanel>

</DataTemplate> </ItemsControl.ItemTemplate>

</ItemsControl> </Grid></phone:PhoneApplicationPage>

Page 10: Developing application for Windows Phone 7 in TDD

XamlXaml

<StackPanel Orientation="Horizontal"> <TextBox x:Name="searchedText" /> <Button Content="Search" Click="Search" /></StackPanel>

Page 11: Developing application for Windows Phone 7 in TDD

XamlXaml

<ItemsControl x:Name="songsList"><ItemsControl.ItemTemplate>

<DataTemplate> <StackPanel Orientation="Horizontal"> <Image Source="{Binding Image}”/>

<TextBlock Text="{Binding Title}"/></StackPanel>

</DataTemplate> </ItemsControl.ItemTemplate></ItemsControl>

Page 12: Developing application for Windows Phone 7 in TDD

Code behind MainViewCode behind MainViewpublic partial class MainView :PhoneApplicationPage { public MainView() { InitializeComponent(); } private void Search(object sender, EventArgs e) { RestClient client = new RestClient { BaseUrl "http://api.soundcloud.com/users/"+searchedText.Text+"/tracks?client_id=eaf7649b0de68f902a4607c0b730e226" }; var request = new RestRequest { RequestFormat = DataFormat.Json };

client.ExecuteAsync<List<Track>>(request, response => { songsList.ItemsSource = response.Data; }); } private void ShowDetail(object sender, GestureEventArgs e) { NavigationService.Navigate(new Uri("/View/DetailView.xaml?id="+ ((Track)((StackPanel)sender).DataContext).Id, UriKind.Relative)); } }

Page 13: Developing application for Windows Phone 7 in TDD

Code behind MainViewCode behind MainViewprivate void Search(object sender, EventArgs e){ RestClient client = new RestClient { BaseUrl "http://api.soundcloud.com/

users/"+searchedText.Text+"/tracks?client_id=eaf7649b0de68f902a4607c0b730e226"

}; var request = new RestRequest {

RequestFormat = DataFormat.Json };

Page 14: Developing application for Windows Phone 7 in TDD

Code behind MainViewCode behind MainView

client.ExecuteAsync<List<Track>>(request, response => { songsList.ItemsSource = response.Data; }); }

Page 15: Developing application for Windows Phone 7 in TDD

Code behind MainViewCode behind MainView private void ShowDetail(object sender, GestureEventArgs e){ NavigationService.Navigate(

new Uri("/View/DetailView.xaml?id="+

((Track)((StackPanel)sender).DataContext).Id, UriKind.Relative

));

}

Page 16: Developing application for Windows Phone 7 in TDD

Xaml DetailViewXaml DetailView<phone:PhoneApplicationPage x:Class="OrangeCode.SoundCloud.View.MainView” > <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions>

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel> <Image x:Name="image" Width="200" Height="200” />

<TextBlock x:Name="creationDate" FontSize="22” /><TextBlock x:Name="title" FontSize="28” /><TextBlock x:Name="description” TextWrapping='Wrap'/>

</StackPanel> </Grid>

</Grid></phone:PhoneApplicationPage>

Page 17: Developing application for Windows Phone 7 in TDD

Xaml DetailViewXaml DetailView

<Grid x:Name="ContentPanel”> <StackPanel> <Image x:Name="image” />

<TextBlock x:Name="creationDate” /><TextBlock x:Name="title” /><TextBlock x:Name="description” />

</StackPanel> </Grid>

Page 18: Developing application for Windows Phone 7 in TDD

Code behind DetailViewCode behind DetailView public partial class DetailView : PhoneApplicationPage { public DetailView() { InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { string id = NavigationContext.QueryString["id"]; RestClient client = new RestClient { BaseUrl = "http://api.soundcloud.com/tracks?client_id=eaf7649b0de68f902a4607c0b730e226&ids=" + id }; var request = new RestRequest { RequestFormat = DataFormat.Json };

client.ExecuteAsync<List<Track>>(request, response => {

image.Source = new BitmapImage(new Uri(response.Data[0].Image)); creationDate.Text = response.Data[0].CreationDate; description.Text = response.Data[0].Description;

title.Text = response.Data[0].Title;

}); } }

Page 19: Developing application for Windows Phone 7 in TDD

Code behind DetailViewCode behind DetailViewprotected override void OnNavigatedTo(NavigationEventArgs e){ string id = NavigationContext.QueryString["id"]; RestClient client = new RestClient { BaseUrl = "http://api.soundcloud.com/tracks?

client_id=eaf7649b0de68f902a4607c0b730e226&ids=" + id

}; var request = new RestRequest {

RequestFormat = DataFormat.Json };

Page 20: Developing application for Windows Phone 7 in TDD

Code behind DetailViewCode behind DetailView

client.ExecuteAsync<List<Track>>(request, response => {

image.Source = new BitmapImage(new Uri(response.Data[0].Image));

creationDate.Text = response.Data[0].CreationDate; description.Text = response.Data[0].Description;

title.Text = response.Data[0].Title;

}); }

Page 21: Developing application for Windows Phone 7 in TDD

Problem with code behindProblem with code behind

• Code coupled with UI– Xaml + Code Behind -> one class

• Not testable

Page 22: Developing application for Windows Phone 7 in TDD

MVVM approachMVVM approach

• Architectural Pattern• Derived from Presentation Model pattern

(Fowler) • Clear separation between UI and Logic

UI ViewModel

Collections, DelegateCommand, Properties

Page 23: Developing application for Windows Phone 7 in TDD

MVVM approachMVVM approach

• Structure our code:– ViewModel (c#): Logic– View (Xaml): Presentation– No more code behind

• Now the ViewModel is testable

Page 24: Developing application for Windows Phone 7 in TDD

Test Driven DevelopmentTest Driven Development

• As easy as complex

• Life Cycle:– Write test (red)– Write logic to pass the test (green)– Refactor code (refactor)– Again..

Page 25: Developing application for Windows Phone 7 in TDD

Test Driven DevelopmentTest Driven Development

• It’s about code design, not test

• Test suite are good side effect of tdd

• It require a lot of discipline and practice

Page 26: Developing application for Windows Phone 7 in TDD

Testing ToolsTesting Tools

• Nunit for Windows Phone 7

• No official mocking framework for Windows Phone 7, but I found out that Moq 3.1 for silverlight works!

Page 27: Developing application for Windows Phone 7 in TDD

TDDTDD

• Download searched user songs list from SoundCloud.com

Page 28: Developing application for Windows Phone 7 in TDD

TDDTDD

• There is a list of track that i’ve to show

Page 29: Developing application for Windows Phone 7 in TDD

TDDTDDnamespace OrangeCode.SoundCloudFixture{ public class MainViewModelFixture { }}

namespace OrangeCode.SoundCloud{ public class MainViewModel { }}

Page 30: Developing application for Windows Phone 7 in TDD

TDD -RedTDD -Red

Write test: [Test]

public void Constructor_Should_Initialize_TrackList() {

MainViewModel viewModel = new MainViewModel(); Assert.IsNotNull(viewModel.Tracks);

}

Page 31: Developing application for Windows Phone 7 in TDD

TDDTDD

You are not allowed to write any production code unless it is to make a failing unit test pass.

Uncle Bob Martin

Page 32: Developing application for Windows Phone 7 in TDD

TDD - RedTDD - Red public class MainViewModel { public IList<Track> Tracks { get ; set ; } }

Page 33: Developing application for Windows Phone 7 in TDD

TDDTDD

Page 34: Developing application for Windows Phone 7 in TDD

TDDTDD

You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

Uncle Bob Martin

Page 35: Developing application for Windows Phone 7 in TDD

TDD - GreenTDD - Green public class MainViewModel { public IList<Track> Tracks { get; set; }

public MainViewModel() { Tracks = new List<Track>(); } }

Page 36: Developing application for Windows Phone 7 in TDD

TDDTDD

Page 37: Developing application for Windows Phone 7 in TDD

TDD –RefactorTDD –Refactor public class MainViewModel{

private IList<Track> _tracks;

public IList<Track> Tracks { get { return _tracks; } }

public MainViewModel() { _tracks = new List<Track>(); } }

Page 38: Developing application for Windows Phone 7 in TDD

TDD - RefactorTDD - Refactor

Page 39: Developing application for Windows Phone 7 in TDD

TDDTDD

• Download searched user songs list from SoundCloud.com

Page 40: Developing application for Windows Phone 7 in TDD

ArchitectureArchitecture

MainViewModel

Ilist<Track>SearchUserTrack(string)

SearchService

Rest Call

Page 41: Developing application for Windows Phone 7 in TDD

ArchitectureArchitecture

MainViewModel

SearchService

Rest Call

public interface ISearchService{ IList<Track> SearchUserTrack(string user);}

public class SearchService : ISearchService{ public IList<Track> SearchUserTrack(string user){ }}

ISearchService

Page 42: Developing application for Windows Phone 7 in TDD

TDDTDD[Test] public void Search_Should_RetrieveSearchedUserTrack (){ Mock<ISearchService> service = new Mock<ISearchService>(); MainViewModel viewModel = new MainViewModel(service.Object); viewModel.SearchedText = "michelecapra"; viewModel.Search.Execute();

service.Verify(p=>p.SearchUserTrack("michelecapra"));}

Page 43: Developing application for Windows Phone 7 in TDD

TDDTDD[Test] public void Search_Should_RetrieveSearchedUserTrack (){ Mock<ISearchService> service = new Mock<ISearchService>(); MainViewModel viewModel = new MainViewModel(service.Object); viewModel.SearchedText = "michelecapra"; viewModel.Search.Execute();

service.Verify(p=>p.SearchUserTrack("michelecapra"));}

Page 44: Developing application for Windows Phone 7 in TDD

TDD - MockTDD - Mock

• Simulated objects that mimic the behavior of real objects in controlled ways

• Mock objects have the same interface as the real objects they mimic, allowing a client object to remain unaware of whether it is using a real object or a mock object.

Page 45: Developing application for Windows Phone 7 in TDD

TDDTDD[Test] public void Search_Should_RetrieveSearchedUserTrack (){ Mock<ISearchService> service = new Mock<ISearchService>(); MainViewModel viewModel = new MainViewModel(service.Object); viewModel.SearchedText = "michelecapra"; viewModel.Search.Execute();

service.Verify(p=>p.SearchUserTrack("michelecapra"));}

Page 46: Developing application for Windows Phone 7 in TDD

TDD- ICommandTDD- ICommand

• The ICommand interface enables the abstraction of a parameterized method call through its Execute method.

• Typically objects implement this interface to enable method calls on the objects through the use of XAML bindings.

Page 47: Developing application for Windows Phone 7 in TDD

TDD- DelegateCommandTDD- DelegateCommand

• ICommand whose delegates can be attached for Execute(T)

• Execute(T) is the method to be called when the command is invoked.

<Button Command=“”></Button>

Page 48: Developing application for Windows Phone 7 in TDD

TDDTDD[Test] public void Search_Should_RetrieveSearchedUserTrack (){ Mock<ISearchService> service = new Mock<ISearchService>(); MainViewModel viewModel = new MainViewModel(service.Object); viewModel.SearchedText = "michelecapra"; viewModel.Search.Execute();

service.Verify(p=>p.SearchUserTrack("michelecapra"));}

Page 49: Developing application for Windows Phone 7 in TDD

TDD - RedTDD - RedAdd properties in order to compile

public string SearchedText { get; set; }

public DelegateCommand Search { get; set; }

Page 50: Developing application for Windows Phone 7 in TDD

TDD - RedTDD - Red

Page 51: Developing application for Windows Phone 7 in TDD

TDD - GreenTDD - Greenpublic string SearchedText { get; set; }

public DelegateCommand Search { get; set; }

public MainViewModel(ISearchService searchService){ _searchService = searchService; _tracks = new List<Track>(); Search = new DelegateCommand(OnSearch);}private void OnSearch(){ _searchService.SearchUserTrack(SearchedText);}

Page 52: Developing application for Windows Phone 7 in TDD

TDD - GreenTDD - Green

Page 53: Developing application for Windows Phone 7 in TDD

TDD - RefactorTDD - Refactorpublic string SearchedText { get; set; }

public DelegateCommand Search { get; private set; }

public MainViewModel(ISearchService searchService){ _searchService = searchService; _tracks = new List<Track>(); Search = new DelegateCommand(OnSearch);}private void OnSearch(){ _searchService.SearchUserTrack(SearchedText);}

Page 54: Developing application for Windows Phone 7 in TDD

TDD - RefactorTDD - Refactor

Page 55: Developing application for Windows Phone 7 in TDD

TDDTDD

• Display the list

Page 56: Developing application for Windows Phone 7 in TDD

TDDTDD[Test]public void Search_Should_UpdateTrackList(){ _searchService.Setup(p => p.SearchUserTrack("michelecapra")).Returns(new List<Track>{new Track()});

_viewModel.SearchedText = "michelecapra"; _viewModel.Search.Execute();

Assert.AreEqual(_viewModel.Tracks.Count, 1);}

Page 57: Developing application for Windows Phone 7 in TDD

TDDTDD[Test]public void Search_Should_UpdateTrackList(){ _searchService.Setup(p => p.SearchUserTrack("michelecapra")).Returns(new List<Track>{new Track()});

_viewModel.SearchedText = "michelecapra"; _viewModel.Search.Execute();

Assert.AreEqual(_viewModel.Tracks.Count, 1);}

Page 58: Developing application for Windows Phone 7 in TDD

TDDTDD[Test]public void Search_Should_UpdateTrackList(){ _searchService.Setup(p => p.SearchUserTrack("michelecapra")).Returns(new List<Track>{new Track()});

_viewModel.SearchedText = "michelecapra"; _viewModel.Search.Execute();

Assert.AreEqual(_viewModel.Tracks.Count, 1);}

Page 59: Developing application for Windows Phone 7 in TDD

TDD - RedTDD - Redpublic string SearchedText { get; set; }

public DelegateCommand Search { get; private set; }

public MainViewModel(ISearchService searchService){ _searchService = searchService; _tracks = new List<Track>(); Search = new DelegateCommand(OnSearch);}private void OnSearch(){ _searchService.SearchUserTrack(SearchedText);}

Page 60: Developing application for Windows Phone 7 in TDD

TDD - RedTDD - Red

Page 61: Developing application for Windows Phone 7 in TDD

TDD - GreenTDD - Greenprivate void OnSearch(){ _tracks= _searchService.SearchUserTrack(SearchedText);}

Page 62: Developing application for Windows Phone 7 in TDD

TDD - GreenTDD - Green

Page 63: Developing application for Windows Phone 7 in TDD

TDDTDD

• View song’s detail

Page 64: Developing application for Windows Phone 7 in TDD

TDDTDD

• We need to introduce the NavigationService

• But how to decouple it from our ViewModel?

Page 65: Developing application for Windows Phone 7 in TDD

TDD – Navigation ServiceTDD – Navigation Servicepublic interface INavigationService{ void NavigateTo(Uri pageUri);}

public class NavigationService : INavigationService{ private static PhoneApplicationFrame _mainFrame;

public event NavigatingCancelEventHandler Navigating;

public void NavigateTo(Uri pageUri) { … }}

THX to

Laurent Bugnion

Page 66: Developing application for Windows Phone 7 in TDD

TDDTDD [Test] public void ShowDetail_Should_NavigateToDetailView() { var navigationService = new Mock<INavigationService>(); var searchService = new Mock<ISearchService>(); var viewModel = new MainViewModel(searchService.Object, navigationService.Object);

viewModel.ShowDetail.Execute(new Track{Id=345});

navigationService.Verify(p => p.NavigateTo(new Uri("/View/DetailView.xaml?id=345", UriKind.Relative))); }

Page 67: Developing application for Windows Phone 7 in TDD

TDDTDD [Test] public void ShowDetail_Should_NavigateToDetailView() { var navigationService = new Mock<INavigationService>(); var searchService = new Mock<ISearchService>(); var viewModel = new MainViewModel(searchService.Object, navigationService.Object);

viewModel.ShowDetail.Execute(new Track{Id=345});

navigationService.Verify(p => p.NavigateTo(new Uri("/View/DetailView.xaml?id=345", UriKind.Relative))); }

Page 68: Developing application for Windows Phone 7 in TDD

TDDTDD [Test] public void ShowDetail_Should_NavigateToDetailView() { var navigationService = new Mock<INavigationService>(); var searchService = new Mock<ISearchService>(); var viewModel = new MainViewModel(searchService.Object, navigationService.Object);

viewModel.ShowDetail.Execute(new Track{Id=345});

navigationService.Verify(p => p.NavigateTo(new Uri("/View/DetailView.xaml?id=345", UriKind.Relative))); }

Page 69: Developing application for Windows Phone 7 in TDD

TDDTDD [Test] public void ShowDetail_Should_NavigateToDetailView() { var navigationService = new Mock<INavigationService>(); var searchService = new Mock<ISearchService>(); var viewModel = new MainViewModel(searchService.Object, navigationService.Object);

viewModel.ShowDetail.Execute(new Track{Id=345});

navigationService.Verify(p => p.NavigateTo(new Uri("/View/DetailView.xaml?id=345", UriKind.Relative))); }

Page 70: Developing application for Windows Phone 7 in TDD

TDD - RedTDD - Red public class MainViewModel { private IList<Track> _tracks; public IList<Track> Tracks { get { return _tracks; } }

public string SearchedText { get; set; } public DelegateCommand Search { get; private set; } public DelegateCommand<Track> ShowDetail{get; set; }

Page 71: Developing application for Windows Phone 7 in TDD

TDD - RedTDD - Redpublic MainViewModel(ISearchService searchService, INavigationService navigationService) { _searchService = searchService; _navigationService = navigationService; _tracks = new List<Track>(); Search = new DelegateCommand(OnSearch); ShowDetail= new DelegateCommand<Track>(OnShowDetail); }

Page 72: Developing application for Windows Phone 7 in TDD

TDD - RedTDD - Redpublic MainViewModel(ISearchService searchService, INavigationService navigationService) { _searchService = searchService; _navigationService = navigationService; _tracks = new List<Track>(); Search = new DelegateCommand(OnSearch); ShowDetail= new DelegateCommand<Track>(OnShowDetail); }

Page 73: Developing application for Windows Phone 7 in TDD

TDD - RedTDD - Red

Page 74: Developing application for Windows Phone 7 in TDD

TDD - GreenTDD - Greenprivate readonly INavigationService _navigationService; …public DelegateCommand<Track> ShowDetail{get; set; }… public MainViewModel(ISearchService searchService, INavigationService navigationService) { _searchService = searchService; _navigationService = navigationService; _tracks = new List<Track>(); Search = new DelegateCommand(OnSearch); ShowDetail= new DelegateCommand<Track>(OnShowDetail); }

Page 75: Developing application for Windows Phone 7 in TDD

TDD - GreenTDD - Greenprivate void OnSearch(){ _tracks= _searchService.SearchUserTrack(SearchedText);}

private void OnShowDetail(Track obj){ _navigationService.NavigateTo(new Uri("/View/DetailView.xaml?id="+obj.Id, UriKind.Relative));}

Page 76: Developing application for Windows Phone 7 in TDD

TDD - GreenTDD - Green

Page 77: Developing application for Windows Phone 7 in TDD

TDD - RefactorTDD - Refactorprivate readonly INavigationService _navigationService;

public DelegateCommand<Track> ShowDetail{get; private set; }

public MainViewModel(ISearchService searchService, INavigationService navigationService) { _searchService = searchService; _navigationService = navigationService; _tracks = new List<Track>(); Search = new DelegateCommand(OnSearch); ShowDetail= new DelegateCommand<Track>(OnShowDetail); }

Page 78: Developing application for Windows Phone 7 in TDD

TDD - RefactorTDD - Refactorprivate void OnSearch(){ _tracks= _searchService.SearchUserTrack(SearchedText);} private void OnShowDetail(Track track){ _navigationService.NavigateTo(new Uri("/View/DetailView.xaml?id=”+track.Id, UriKind.Relative));}

Page 79: Developing application for Windows Phone 7 in TDD

TDD - RefactorTDD - Refactor

Page 80: Developing application for Windows Phone 7 in TDD

TDD – Test suite refactorTDD – Test suite refactor [Test] public void ShowDetail_Should_NavigateToDetailView() { var navigationService = new Mock<INavigationService>(); var searchService = new Mock<ISearchService>(); var viewModel = new MainViewModel(searchService.Object, navigationService.Object);

viewModel.ShowDetail.Execute(new Track{Id=345});

navigationService.Verify(p => p.NavigateTo(new Uri("/View/DetailView.xaml?id=345", UriKind.Relative))); }

Page 81: Developing application for Windows Phone 7 in TDD

TDD – Test suite refactorTDD – Test suite refactor [Test] public void ShowDetail_Should_NavigateToDetailView() { var navigationService = new Mock<INavigationService>(); var searchService = new Mock<ISearchService>(); var viewModel = new MainViewModel(searchService.Object, navigationService.Object);

viewModel.ShowDetail.Execute(new Track{Id=345});

navigationService.Verify(p => p.NavigateTo(new Uri("/View/DetailView.xaml?id=345", UriKind.Relative))); }

Page 82: Developing application for Windows Phone 7 in TDD

public class MainViewModelFixture{ private Mock<INavigationService> _navigationService; private Mock<ISearchService> _searchService; private MainViewModel _viewModel;

[SetUp] public void Setup() { _navigationService = new Mock<INavigationService>(); _searchService = new Mock<ISearchService>(); _viewModel = new MainViewModel(_searchService.Object, _navigationService.Object); }

TDD – Test suite refactorTDD – Test suite refactor

Page 83: Developing application for Windows Phone 7 in TDD

public class MainViewModelFixture{ private Mock<INavigationService> _navigationService; private Mock<ISearchService> _searchService; private MainViewModel _viewModel;

[SetUp] public void Setup() { _navigationService = new Mock<INavigationService>(); _searchService = new Mock<ISearchService>(); _viewModel = new MainViewModel(_searchService.Object, _navigationService.Object); }

TDD – Test suite refactorTDD – Test suite refactor

Page 84: Developing application for Windows Phone 7 in TDD

ViewModel and UIViewModel and UI

• FrameworkElement.DataContext• “A directly embedded object that

serves as data context for any bindings within the parent element”

• We’ll put here our ViewModel!

<phone:PhoneApplicationPage DataContext=“”/>

Page 85: Developing application for Windows Phone 7 in TDD

ViewModel and UIViewModel and UIpublic partial class MainView :PhoneApplicationPage{ public MainView() { InitializeComponent(); DataContext = new MainViewModel(new SearchService(), new NavigationService()); }}

Page 86: Developing application for Windows Phone 7 in TDD

MainViewMainView<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

<Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions>

<StackPanel Orientation="Horizontal"><TextBox Text="{Binding Text,Mode=TwoWay}” /><Button Content="Search" Command="{Binding Search}"

HorizontalAlignment="Right" ></StackPanel>

Page 87: Developing application for Windows Phone 7 in TDD

MainViewMainView<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

<Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions>

<StackPanel Orientation="Horizontal"><TextBox Text="{Binding Text,Mode=TwoWay}” /><Button Content="Search" Command="{Binding Search}"

HorizontalAlignment="Right" ></StackPanel>

Page 88: Developing application for Windows Phone 7 in TDD

MainViewMainView<ItemsControl Grid.Row="1" ItemsSource="{Binding Tracks}” >

<ItemsControl.ItemTemplate>

<DataTemplate>

<StackPanel Orientation="Horizontal" Tap="ShowDetail">

<Image Source="{Binding Image}" />

<TextBlock Text="{Binding Title}"/>

</StackPanel>

</DataTemplate>

</ItemsControl.ItemTemplate>

</ItemsControl>

Page 89: Developing application for Windows Phone 7 in TDD

MainViewMainView<ItemsControl Grid.Row="1" ItemsSource="{Binding Tracks}” >

<ItemsControl.ItemTemplate>

<DataTemplate>

<StackPanel Orientation="Horizontal" Tap="ShowDetail">

<Image Source="{Binding Image}" />

<TextBlock Text="{Binding Title}"/>

</StackPanel>

</DataTemplate>

</ItemsControl.ItemTemplate>

</ItemsControl>

Page 90: Developing application for Windows Phone 7 in TDD

INotifyPropertyChangedINotifyPropertyChanged

• INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed.

Page 91: Developing application for Windows Phone 7 in TDD

INotifyPropertyChangedINotifyPropertyChanged public class MainViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String name) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(name)); } }

Page 92: Developing application for Windows Phone 7 in TDD

INotifyPropertyChangedINotifyPropertyChanged private void ExecuteSearch() { _tracks=_service.SearchUserTrack(SearchedUser); NotifyPropertyChanged(”Tracks"); }}

Page 93: Developing application for Windows Phone 7 in TDD

RecapRecap

What we have seen:-TDD (unit test, mock)-MVVM (commanding, binding, INotifyPropertyChanged, DataContext)

Page 94: Developing application for Windows Phone 7 in TDD

Node.JSNode.JS

Page 95: Developing application for Windows Phone 7 in TDD

Be in contactBe in contact

Mail: [email protected]: @piccoloaiutanteWeb: www.orangecode.itBlog: www.orangecode.it/blogGitHub: https://github.com/piccoloaiutante

Community: WEBdeBS

Page 96: Developing application for Windows Phone 7 in TDD

That’s all folksThat’s all folks