MvvmCross - James Montemagno https://staging.montemagno.com/tag/mvvmcross/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png MvvmCross - James Montemagno https://staging.montemagno.com/tag/mvvmcross/ Hugo -- gohugo.io Tue, 13 Oct 2026 23:21:57 GMT 60 Xamarin.Android SwipeRefreshLayout for #MvvmCross https://staging.montemagno.com/xamarinandroid-swiperefreshlayout-for-mvvmcross/ 598df8f2c121b60019bf3037 Tue, 08 Apr 2014 16:30:00 GMT I was very excited to see that the latest version of Support v4 for Android was updated to include as most people would says it a “Pull to Refresh”… or as Google would call it a “SwipeRefreshLayout”. It is now available in the Xamarin.Android Support v4 Component so we should probably take advantage of it! This is actually a really slick Layout that you can make the parent of any 1 layout and when the user swipes down on it you will get notified that you are supposed to refresh the content. This means you can now get rid of all of your refresh icon buttons in your UI and follow the same patterns Google has for their apps that your users will be used to.

Naturally I wanted to implement an MvvmCross version of this since I did an MvvmCross binding for UIRefreshControl on iOS a while back. So the goals here are simple:

  1. Execute an ICommand when someone pulls down to refresh

  2. Bind a bool to begin and end the refreshing spinner

So I created a very very simple MvxSwipeRefreshLayout which you can find the Gist for RIGHT HERE! In addition you will just need to implement a bit of code in your .axml layout and in your code behind to set the Refresh command.

]]>
MvvmCross + ActionBarCompat (v7 Support) https://staging.montemagno.com/mvvmcross-actionbarcompat-v7-support/ 598df8f2c121b60019bf303d Fri, 27 Dec 2013 04:59:00 GMT If you are using MvvmCross (if you aren’t you should) then you might notice that there is no official MvxActionBarActivity to use. This is sad because if you are using the new Support v7 Library then this will be a must. I am sure Stuart is going to add this or create a NuGet for it, but you can do it today by creating 2 new classes.

Since MvxActivity inherits from MvxEventSourceActivity you will need to re-implement these classes. Usually this would be frowned upon as the framework is always changing, but these things have been around for ever and don’t really need updating. So here is what you will need to copy in:

Boom you are all set

]]>
Simple re-usable Swipe To Delete Xamarin.iOS + MvvmCross https://staging.montemagno.com/simple-re-usable-swipe-to-delete-xamarinios/ 598df8f2c121b60019bf3046 Tue, 15 Oct 2013 02:04:35 GMT I was recently implementing some swipe to delete and edit mode in my Xamarin.iOS/MvvmCross applications. It is very common that you will have a custom TableViewDataSource that will implement and override some methods to handle this for you. It is very well documented on the Xamarin website. However I have always found myself writing the same code over and over again for custom data source. With MvvmCross we should all be about the code re-use. So I broke it down into this:

  1. A simple IRemove.cs interface that has one ICommand to remove an item.
  2. Implement this interface in ANY ViewModel
  3. A custom MvxStandardTableViewSource that will handle the delete overrides and takes an IRemove class.

That is is really!

Here is the interface:

public interface IRemove
{
  ICommand RemoveCommand { get; }
}

The “MvxDeleteStandardTableViewSource” Impelemtnation

public class MvxDeleteStandardTableViewSource : MvxStandardTableViewSource
{

  private IRemove m_ViewModel;

#region Constructors
  public MvxDeleteStandardTableViewSource(IRemove viewModel, UITableView tableView, UITableViewCellStyle style, NSString cellIdentifier, IEnumerable<MvxBindingDescription> descriptions, UITableViewCellAccessory tableViewCellAccessory = 0)
			: base(tableView, style, cellIdentifier, descriptions, tableViewCellAccessory)
  {
    m_ViewModel = viewModel;
  }

  public MvxDeleteStandardTableViewSource(IRemove viewModel, UITableView tableView, string bindingText) : base(tableView, bindingText)
  {
    m_ViewModel = viewModel;
  }

  public MvxDeleteStandardTableViewSource(IRemove viewModel, UITableView tableView, NSString cellIdentifier) : base(tableView, cellIdentifier)
  {
    m_ViewModel = viewModel;
  }

  public MvxDeleteStandardTableViewSource(IRemove viewModel, UITableView tableView) : base(tableView)
  {
    m_ViewModel = viewModel;
  }

  public MvxDeleteStandardTableViewSource(IRemove viewModel, UITableView tableView, UITableViewCellStyle style, NSString cellId, string binding, UITableViewCellAccessory accessory)
			: base(tableView, style, cellId, binding, accessory)
  {
    m_ViewModel = viewModel;
  }
#endregion

  public override bool CanEditRow(UITableView tableView, NSIndexPath indexPath)
  {
    return true;
  }

  public override void CommitEditingStyle(UITableView tableView, UITableViewCellEditingStyle editingStyle, NSIndexPath indexPath)
  {
    switch (editingStyle)
    {
      case UITableViewCellEditingStyle.Delete:
        m_ViewModel.RemoveCommand.Execute(indexPath.Row);
        break;
      case UITableViewCellEditingStyle.None:
        break;
      }
  }

  public override UITableViewCellEditingStyle EditingStyleForRow(UITableView tableView, NSIndexPath indexPath)
  {
    return UITableViewCellEditingStyle.Delete;
  }

  public override bool CanMoveRow(UITableView tableView, NSIndexPath indexPath)
  {
    return false;
  }
}

Here is my implementation in my view model:

private MvxCommand<int> m_RemoveCommand;
public ICommand RemoveCommand
{
get => m_RemoveCommand ?? (m_RemoveCommand = new MvxCommand<int>(i => this.m_List.RemoveAt(i)));
}

Then in your View you will just need to setup this:

m_TableView = new UITableView();
Add(m_TableView);

var source = new MvxDeleteStandardTableViewSource (ViewModel, m_TableView, UITableViewCellStyle.Subtitle, new NSString("my_id"), "TitleText Title;DetailText Subtitle;ImageUrl Image", UITableViewCellAccessory.None);
m_TableView.Source = source;

Boom now you are getting sweet swipe to delete with ease!

I also have a full Gist on GitHub!

The possibilities are endless here as well. Your IRemove interface could also have something like a string for what to say (instead of delete) or a method that returns it based on the index. You could also apply this for the drag/drop as well, which would be pretty simple.

]]>
Effective Navigation in Xamarin.Android: Part 1 - Navigation Drawer https://staging.montemagno.com/effective-navigation-in-xamarinandroid-part-1/ 598df8f2c121b60019bf3049 Fri, 06 Sep 2013 04:56:00 GMT When designing your app you have probably wondered about what type of navigation is the best to use. Dashboards, navigation lists, spinner drop downs, tabs, and fly out menus are all still prevalent and valid choices, however, Google has recently made a huge push to use their new standard Navigation Drawer control.

So what is a Navigation Drawer?

Similar to a flyout menu made famous by Facebook, the Navigation Drawer is designed to be swiped out from the left side of you application. The main difference is the navigation drawer slides on top of your main content and dims it out. This is unlike flyout which actually pushes your content off screen and is more jarring for your user.

As you can see here, the user will slide or press the home button to slide out the navigation drawer, and then select which section they would like to go to next.

Why Navigation Drawer?

1.) Now a standard control in the Support v4 library and ties directly into the Action Bar.

2.) Easy to implement with a Fragment first approach.

3.) Highly customizable. Use for navigation, account selection, or a combination of both. The possibilities are endless really.

4.) User familiarity as Google and others have already upgraded nearly all of their applications to follow this navigation scheme.

Let’s Code!

So enough background on the Navigation Drawer. Let’s write some code in Xamarin.Android!

When designing for the Navigation Drawer, you should first think of your apps flow. The navigation drawer is part of your main activity and is a container for all other sections, which are fragments that are swapped in and out. In this example I have the following:

  • Home Activity: Consists of Navigation Drawer Layout
  • Browse Fragment: Grid of images to browse through
  • Friends Fragment: Contains a ViewPager with friends list
  • Profile Fragment: Contains a small profile and image of the user

Create your Drawer Layout: This is the standard layout that Google recommends, which is a “DrawerLayout” as the root object with a “FrameLayout” to contain your main content or fragments that you will swap in and out. After that, you then have a “ListView” which is your actual Navigation Drawer. In this example we will just use a standard list, but you could completely customize it with headers, footers, or change it to something completely different.

Initialize the Drawer List

In this sample, I am simply creating an array of sections that my application might have, however you can customize your ListView to have a custom adapter that will display images or other information.

The last thing I am doing here is registering for an ItemClick event on my ListView to detect when the user selects a section.

Handle Navigation Click Events

Since we have registered for an ItemClick event “DrawerListOnItemClick” we will implement this method to replace the Resource.Id.content_frame with the fragment that the user has selected based on the position.

In this example I am using the SupportFragmentManager because I am going to be using a ViewPagerIndicator which takes Support v4 Fragments. However, if you are not using this you are free to use the standard FragmentManager. After I replace and commit the fragment, the last things to do are to set the correct checked position in the ListView, update the ActionBar with the title of the current fragments, and most importantly, close the drawer.

Listen for Drawer Events with ActionBarDrawerToggle

Each DrawLayout has a DrawerListener which is an ActionBarDrawerToggle that is used to notify us when the Drawer is opened, closed, state changed, or had slid open. In the sample you will find a class called “MyActionBarDrawerToggle.cs,” which implements all of the proper methods.

You will want to create a new “MyActionBarDrawerToggle” in your OnCreate, which takes in the current Activity, the icon to use, and a few strings to display if the user long presses on the toggle. After you have created the new Toggle you will want to implement the DrawerOpen and DrawerClosed events to update the ActionBar title and to also update the OptionsMenu. Finally you need to set the DrawerListener for your Drawer to actually listen for these events.

The standard drawer icons can be downloaded from Google.

Wrapping it up:

The other last few steps allow the user to open and close the navigation drawer by touching the app icon in the ActionBar. Simply set the SetDisplayHomeAsUpEnabled and SetHomeButtonEnabled in your OnCreate and then ensure that you synchronize your DrawerToggle throughout the main activities lifecycle.

Compatibility:

The navigation drawer ties directly into ActionBar, so if you are looking to target older platforms look into using ActionBarSherlock or the new ActionBarCompat(support v7) libraries. Full MvvmCross support is also available with a little adjustment by using a CustomPresenter to intercept navigation to present the fragments. A full example is available on GitHub.

Fragments inside of fragments!

Everything inside of the navigation drawer is a fragment, so that can lead to some interesting scenarios if you are using something like a ViewPagerIndicator, which also consists of fragments. Do not fear as you can use nested fragments! Simply provide the ChildFragmentManager instead of the standard FragmentManager and this will cover you!

Design Consideration:

Override OnPrepareOptionsMenu and remove any action items that are related to the content view. It is best practice to only show action items that pertain to the Navigation Drawer when it is open.

After the user first installs your application you might want to open the Navigation Drawer when they first load your application. This will allow your users to become familiar with the different sections of your application.

There you have it! A beautiful navigation model for your application. Check out full sample code available on GitHub.

Update! I presented on Navigation at Xamarin Evolve 2014:

]]>
MvxUIRefreshControl for #MvvmCross In iOS6+ land adding pull to refresh is EXTREMELY simple. You can read all about it, but basically you need to just implement 1 method and you can even set a custom string and …]]> https://staging.montemagno.com/mvxuirefreshcontrol-for-mvvmcross/ 598df8f2c121b60019bf304a Fri, 23 Aug 2013 19:38:10 GMT Implementing MvxTableViews and MvxCollectionViews are extremely simple. From binding to accessory or cell clicks, to implementing advanced logic for custom cells they just plain work in MvvmCross. However, today I ran into one issue that needed to be solved, an Mvx binding for UIRefreshControl. <br./></br.>

In iOS6+ land adding pull to refresh is EXTREMELY simple. You can read all about it, but basically you need to just implement 1 method and you can even set a custom string and style it. It is beautiful, however there was no way to bind anything in MvvmCross. So I wanted to create a simple binding to accomplish a few goals:

1.) Execute an ICommand when someone pulls down to refresh

2.) Bind a bool to begin and end the refreshing spinner

3.) Bind a string to set the AttributedTitle (what is displayed to the user) when they pull or when it refreshes.

So I created a very very simple UIRefreshControl, which you can find on Gist RIGHT HERE

The code is as simple to implement as:

var refreshControl = new MvxUIRefreshControl();
this.RefreshControl = refreshControl;

var set = this.CreateBindingSet<MyView, MyViewModel>();
set.Bind(refreshControl).For(r => r.IsRefreshing).To(vm => vm.IsBusy);
set.Bind(refreshControl).For(r => r.RefreshCommand).To(vm => vm.ReloadCommand);
set.Bind(refreshControl).For(r => r.Message).To(vm => vm.BusyMessage);
set.Apply();

I hope this helps

]]>
NuGets Everywhere! VS or XS! https://staging.montemagno.com/nugets-everywhere-vs-or-xs/ 598df8f2c121b60019bf304b Wed, 21 Aug 2013 17:58:00 GMT Alright so a quick follow up to that huge blog I just wrote about PCLs. So PCLs are great for your core, but are also great because you can share PCLs with people and they will work everywhere. On Visual Studio there is a great Nuget Package Manager already that you can grab and install. If you are using Xamarin Studio you have a pretty great option as well with THIS Addin

Our team here at Ceton does a bit of cross development on both Mac and on Visual Studio. If you are doing WP or Windows Store apps then this is a must. I prefer to create all of my base solutions and projects inside of VS first. Get some Nugets going with the nuget manager and the most important part is to ENABLE NUGET PACKAGE RESTORE!!! Simply right click on your project and say… Enable Nuget Package Restore. This will allow you to sync up your nugets over on XS.

Alright so let’s say you got all your packages up and running in VS how do you sync them over in Xamarin Studio???

The first thing you will need to do is go into the .nuget folder that VS has created and you will find Nuget.targets. For some reason if you have nugets it will try to auto update them, if this is works for you then great, however XS has ALWAYS thrown an error for me, so I say hey let’s just do it manually. So a bit down you sill see somethign that says “NuGet command” after the platform specific code. Well let’s NOT let this run unless we are on windows so add “ Condition=” ’$(OS)’ == ‘Windows_NT’“ to that Property group

Alright awesome!!

So now you will have to create a script over on your MAC to update your Nugets.. This is kind of a pain but you only have to do it every once in a while.

1.) In terminal go to your_project/.nuget

2.) Make script executable "chmod 755 osxnuget.sh”

3.) Fill in the script: it should be something like this:

mozroots --import --sync
mono --runtime=v4.0.30319 NuGet.exe
mono --runtime=v4.0.30319 NuGet.exe install ../project.core/packages.config -Output ../packages
mono --runtime=v4.0.30319 NuGet.exe install ../project.test/packages.config -Output ../packages
mono --runtime=v4.0.30319 NuGet.exe install ../project.ui.android/packages.config -Output ../packa

4.) Run it with “./osxnuget.sh”

If XS was open simply restart it.

Boom you are good to go again!

]]>