Monthly Archives: December 2022

ImageButton or Image with TapGestureRecognizer in MAUI ?

MAUI includes a Button (as you’d expect) as well as an ImageButton which allows us to display (as I’m sure you guessed) and image instead of text. Sadly (at least in the current version of .NET 7.0) this does not work nicely on Windows and I want my MAUI app to deploy to iOS, Android and Windows.

An Image Button takes and image source and we can supply a command etc. like this

<ImageButton 
   Source="start.png" 
   Command="{Binding StartCommand}" />

I’ve not tested this yet on a device, but on an Android emulator the image button doesn’t have the pressed, ripple effect that a standard button has, so it’s not that obvious that it’s been clicked. However it displays the image correctly and with transparency. Much to my surprise though, on Windows, the transparency is lost and instead we get a button with some percentage of opacity, however on Windows it does look more like a button – so good and bad points.

So, at this time, the best way to display an image and respond to tap events appears to still be using an Image and TapGestureRecognizer, like this

<Image Source="start.png">
   <Image.GestureRecognizers>
      <TapGestureRecognizer Command="{Binding StartStopCommand}"/>
   </Image.GestureRecognizers>
</Image>

This still lacks the button-like feedback (such as a ripple). Using something like the AlohaKit.Animations NuGet package we could add a Tapped event to our TapGestureRecognizer and in code behind have something like

private void TapGestureRecognizer_OnTapped(object? sender, TappedEventArgs e)
{
   if (sender is View view)
   {
      view.Animate(new StoryBoard(new List<AnimationBase>
      {
         new ScaleToAnimation { Scale = 1.2, Duration = "200" },
         new ScaleToAnimation { Scale = 1, Duration = "100" }
      }));
   }
}

Whilst it’s not a button ripple effect, it does give some feedback on the image being tapped – obviously it would be worth looking at alternative animations to best suit your needs.

Unit testing your MAUI project

Note: I found this didn’t work correctly on Visual Studio for Mac, I’ll update the post further if I do get it working.

This post is pretty much a duplicate of Adding xUnit Test to your .NET MAUI Project but just simplified for me to quickly repeat the steps which allow me to write unit tests against my MAUI project code.

So, you want to unit test some code in your MAUI project. It’s not quite as simple as just creating a test project then referencing the MAUI project. Here are the steps to create an NUnit test project with .NET 7 (as my MAUI project has been updated to .NET 7).

  • Add a new NUnit Test Project to the solution via right mouse click on the solution, Add | Project and select NUnit Test Project
  • Open the MAUI project (csproj) file and prepend the net7.0 to the TargetFrameworks so it looks like this
    <TargetFrameworks>net7.0;net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
    
  • Replace <OutputType>Exe</OutputType> with the following
    <OutputType Condition="'$(TargetFramework)' != 'net7.0'">Exe</OutputType>
    

    Yes, this is TargetFramework singular. You may need to reload the project.

  • Now in your unit test project you can reference this MAUI project and write your tests

So, why did we carry out these steps?

Our test project was targeting .NET 7.0 but our MAUI project was targeting different platform implementations of the .NET 7 frameworks, i.e those for Android etc. We need the MAUI project to build a .NET 7.0 compatible version hence added the net7.0 to the TargetFrameworks.

The change to add the OutputType ensures that we only build an EXE output for those other frameworks, and therefore for .NET 7.0 we’ll have a DLL to reference instead in our tests.

Now we can build and run our unit tests.