Click here to Skip to main content
15,879,535 members
Articles / Mobile Apps / Windows Phone 7

Property Finder – a Cross-Platform Xamarin MonoTouch Mobile App

Rate me:
Please Sign up or sign in to vote.
5.00/5 (17 votes)
3 Jan 2013CPOL19 min read 78.4K   1.2K   48  
A look at how Xamarin MonoTouch allows you to create cross-platform applications, using the native C# / Silverlight for Windows Phone and C#, via Xamarin MonoTouch, for iOS.
using System;
using System.Collections.Generic;
using PropertyFinder.Model;

namespace PropertyFinder.Presenter
{
  /// <summary>
  /// A presenter for the front-page of this application This presenter allows the
  /// user to search by a text string or their current location.
  /// </summary>
  public class PropertyFinderPresenter
  {
    /// <summary>
    /// The interface this presenter requires from the assocaited view.
    /// </summary>
    public interface View
    {
      /// <summary>
      /// Sets the text displayed in the search field.
      /// </summary>
      string SearchText { set; }

      /// <summary>
      /// Supplies a message to the user, typically to indicate an error or problem.
      /// </summary>
      void SetMessage(string message);

      /// <summary>
      /// Displays a list of suggested locations when the user supplies a plain-text search.
      /// </summary>
      void DisplaySuggestedLocations(List<Location> locations);

      /// <summary>
      /// Displays a list of recently performed searches
      /// </summary>
      void DisplayRecentSearches(List<RecentSearch> recentSearches);

      /// <summary>
      /// Sets whether to display a loading indicator
      /// </summary>
      bool IsLoading { set; }

      event EventHandler SearchButtonClicked;

      event EventHandler<SearchTextChangedEventArgs> SearchTextChanged;

      event EventHandler MyLocationButtonClicked;

      event EventHandler FavouritesClicked;

      event EventHandler<LocationSelectedEventArgs> LocationSelected;

      event EventHandler<RecentSearchSelectedEventArgs> RecentSearchSelected;
    }

    private View _view;

    private PropertyDataSource _propertyDataSource;

    private INavigationService _navigationService;

    private PropertyFinderPersistentState _state;

    private IGeoLocationService _geolocationService;

    private SearchItemBase _searchItem = new PlainTextSearchItem("");

    public PropertyFinderPresenter(PropertyFinderPersistentState state,
      PropertyDataSource dataSource, INavigationService navigationService, IGeoLocationService geolocationService)
    {
      _propertyDataSource = dataSource;
      _navigationService = navigationService;
      _state = state;
      _geolocationService = geolocationService;
    }

    public void SetView (View view)
    {
      _view = view;
      _view.SearchButtonClicked += View_SearchButtonClicked;
      _view.LocationSelected += View_LocationSelected;
      _view.FavouritesClicked += View_FavouritesClicked;
      _view.MyLocationButtonClicked += View_MyLocationButtonClicked;
      _view.SearchTextChanged += View_SearchTextChanged;
      _view.RecentSearchSelected += View_RecentSearchSelected;

      _view.DisplayRecentSearches (_state.RecentSearches.Count > 0 ? _state.RecentSearches : null);
    }

    private void View_RecentSearchSelected (object sender, RecentSearchSelectedEventArgs e)
    {
      _searchItem = e.RecentSearch.Search;
      _view.SearchText = e.RecentSearch.Search.DisplayText;
      SearchForProperties();
    }
    
    private void View_SearchTextChanged(object sender, SearchTextChangedEventArgs e)
    {
      if (e.Text != _searchItem.DisplayText)
      {
        _searchItem = new PlainTextSearchItem(e.Text);
      }
    }

    private void View_MyLocationButtonClicked(object sender, EventArgs e)
    {
      _view.IsLoading = true;
      _geolocationService.GetLocation(location =>
        {
          _view.IsLoading = false;

          if (location == null)
          {
            _view.SetMessage("Unable to detect current location. Please ensure location is turned on in your phone settings and try again.");
          }
          else
          {
            _searchItem = new GeoLocationSearchItem(location);
            _view.SearchText = _searchItem.DisplayText;
            SearchForProperties();
          }
        });
    }

    private void View_FavouritesClicked(object sender, EventArgs e)
    {
      var presenter = new FavouritesPresenter(_navigationService, _state);
      _navigationService.PushPresenter(presenter);
    }

    private void View_LocationSelected(object sender, LocationSelectedEventArgs e)
    {
      _view.SearchText = e.Location.DisplayName;
      _view.DisplaySuggestedLocations(null);
      _searchItem = new PlainTextSearchItem(e.Location.Name, e.Location.DisplayName);
      SearchForProperties();
    }

    private void View_SearchButtonClicked(object sender, EventArgs e)
    {
      SearchForProperties();
    }

    private void SearchForProperties()
    {
      _view.IsLoading = true;

      _view.SetMessage(null);

      _searchItem.FindProperties(_propertyDataSource, 1, response =>
      {
        if (response is PropertyListingsResult)
        {
          var propertiesResponse = (PropertyListingsResult)response;
          if (propertiesResponse.Data.Count == 0)
          {
            _view.SetMessage("There were no properties found for the given location.");
          }
          else
          {
            var listingsResponse = (PropertyListingsResult)response;
            _state.AddSearchToRecent(new RecentSearch(_searchItem, listingsResponse.TotalResult));
            _view.DisplayRecentSearches(_state.RecentSearches);
            var presenter = new SearchResultsPresenter(_navigationService, _state, listingsResponse,
                                                        _searchItem, _propertyDataSource);
            _navigationService.PushPresenter(presenter);
          }
        }
        else if (response is PropertyLocationsResult)
        {
          _view.DisplayRecentSearches(null);
          _view.DisplaySuggestedLocations(((PropertyLocationsResult)response).Data);
        }
        else
        {
          _view.SetMessage("The location given was not recognised.");
        }

        _view.IsLoading = false;
      }, error =>
      {
        _view.SetMessage("An error occurred while searching. Please check your network connection and try again.");
        _view.IsLoading = false;
      });
    }
  }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Scott Logic
United Kingdom United Kingdom
I am CTO at ShinobiControls, a team of iOS developers who are carefully crafting iOS charts, grids and controls for making your applications awesome.

I am a Technical Architect for Visiblox which have developed the world's fastest WPF / Silverlight and WP7 charts.

I am also a Technical Evangelist at Scott Logic, a provider of bespoke financial software and consultancy for the retail and investment banking, stockbroking, asset management and hedge fund communities.

Visit my blog - Colin Eberhardt's Adventures in .NET.

Follow me on Twitter - @ColinEberhardt

-

Comments and Discussions