Skip to content

Commit

Permalink
Update Migration Guide Based On MCT Changes
Browse files Browse the repository at this point in the history
We're now setting the binding context automatically on the TouchBehavior so I've updated the docs to reflect the current state of the feature
  • Loading branch information
Axemasta committed Apr 3, 2024
1 parent acff874 commit 5c8a036
Showing 1 changed file with 27 additions and 66 deletions.
93 changes: 27 additions & 66 deletions docs/maui/behaviors/touch-behavior.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,16 +273,36 @@ You can find the source code for `TouchBehavior` over on the [.NET MAUI Communit

## Migrating From Xamarin Community Toolkit

In the [Xamarin Community Toolkit](https://github.com/xamarin/XamarinCommunityToolkit), there was the [`TouchEffect`](/dotnet/api/xamarin.communitytoolkit.effects.toucheffect?view=xamarin-community-toolkit-sdk) if you are upgrading an app from Xamarin.Forms to .NET Maui there are a number of changes that you need to be aware of:
1. [`TouchBehavior` is now a `PlatformBehavior`](#TouchBehavior-is-now-a-PlatformBehavior)
2. [The `BindingContext` is not automatically set](#Setting-The-TouchBehavior-Binding-Context)

### TouchBehavior is now a PlatformBehavior
In the [Xamarin Community Toolkit](https://github.com/xamarin/XamarinCommunityToolkit), there was the [`TouchEffect`](/dotnet/api/xamarin.communitytoolkit.effects.toucheffect?view=xamarin-community-toolkit-sdk) if you are upgrading an app from Xamarin.Forms to .NET Maui there are some breaking changes that you should be aware of:
1. [API Name Changes](#API-Name-Changes)
2. [TouchBehavior is now implemented as a `PlatformBehavior`](#TouchBehavior-is-now-implemented-as-a-`PlatformBehavior`)

### API Name Changes

| Name In Xamarin Community Toolkit | Name In Maui Community Toolkit |
|-----------------------------------|------------------------------------------------------|
| TouchEffect | TouchBehavior |
| NormalBackgroundColor | DefaultBackgroundColor |
| NormalScale | DefaultScale |
| NormalOpacity | DefaultOpacity |
| NormalTranslationX | DefaultTranslationX |
| NormalTranslationY | DefaultTranslationY |
| NormalRotation | DefaultRotation |
| NormalRotationX | DefaultRotationX |
| NormalRotationY | DefaultRotationY |
| NormalAnimationDuration | DefaultAnimationDuration |
| NormalAnimationEasing | DefaultAnimationEasing |
| NormalBackgroundImageSource | DefaultImageSource (Moved to `ImageTouchBehavior`) |
| NormalBackgroundImageAspect | DefaultImageAspect (Moved to `ImageTouchBehavior` ) |

### TouchBehavior is now implemented as a `PlatformBehavior`

In the Xamarin Community Toolkit the `TouchEffect` was implemented as an `AttachedEffect`. To use the effect you would use the attached properties and apply to any `VisualElement`

In .NET Maui the `TouchBehavior` is implemented as a `PlatformBehavior` behavior is now applied to the elements behavior collection, see [Platform Behaviors](/dotnet/maui/fundamentals/behaviors#platform-behaviors) for more information.
In .NET Maui the `TouchBehavior` is implemented as a `PlatformBehavior` which is now applied to the elements behavior collection, see [Platform Behaviors](/dotnet/maui/fundamentals/behaviors#platform-behaviors) for more information.

> Note: By default in .NET Maui `PlatformBehavior`s will not set a BindingContext, this is because Behaviors can be shared in styles. The `TouchBehavior` will set it's `BindingContext` equal to the `VisualElement` it is applied to. This means that you should not share the `TouchBehavior` between elements via styles.

Below is an example of a `TouchEffect` being applied to a view in Xamarin Forms:

Expand Down Expand Up @@ -325,63 +345,4 @@ The equivalent `TouchBehavior` in .NET Maui would look like this:
HeightRequest="100"
WidthRequest="10" />
</HorizontalStackLayout>
```

### Setting The TouchBehavior Binding Context

As noted in the previous section, the `BindingContext` of the behavior is not set automatically, the reason for this is outlined in the Maui documentation for [Behaviors](/dotnet/maui/fundamentals/behaviors#create-a-net-maui-behavior):

> .NET MAUI does not set the BindingContext of a behavior, because behaviors can be shared and applied to multiple controls through styles.

You should note that whilst .NET Maui behaviors can be shared via styles, the `TouchBehavior` is inteded to be applied to a specific `VisualElement` and should not be shared across multiple views. A new instance of the `TouchBehavior` should be created for every `VisualElement` it is applied to.

Since the `TouchBehavior` does not inherit any `BindingContext`, the use of [Relative bindings](/dotnet/maui/fundamentals/data-binding/relative-bindings) is unsupported since the behavior has no way of obtaining any information about the `BindingContext` of the `VisualElement` it is applied to. Instead you should use an element in your view as an anchor to provide the `BindingContext` for the `TouchBehavior` using an `x:Reference`.

You can set an `x:Name` on any element on page to set the `BindingContext` of the `TouchBehavior` to your respective viewmodel. A convenient way of doing this is setting this at the root element of your view, for example the `ContentPage`.

```xaml
<ContentPage x:Name="Page">
<HorizontalStackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="Center">
<HorizontalStackLayout.Behaviors>
<mct:TouchBehavior
BindingContext="{Binding Source={x:Reference Page}, Path=BindingContext}"
Command="{Binding IncreaseTouchCountCommand}"
DefaultAnimationDuration="250"
DefaultAnimationEasing="{x:Static Easing.CubicInOut}"
PressedOpacity="0.6"
PressedScale="0.8" />
</HorizontalStackLayout.Behaviors>

<ContentView
BackgroundColor="Gold"
HeightRequest="100"
WidthRequest="10" />
<Label
LineBreakMode="TailTruncation"
Text="The entire layout receives touches"
VerticalOptions="Center" />
<ContentView
BackgroundColor="Gold"
HeightRequest="100"
WidthRequest="10" />
</HorizontalStackLayout>
</ContentPage>
```

If you are using a templated view, such as a `DataTemplate` you should use the parent view instead:

```xaml
<DataTemplate x:DataType="models:User">
<ContentView x:Name="ContentView">
<ContentView.Behaviors>
<mct:TouchBehavior BindingContext="{Binding Source={x:Reference ContentView}, Path=BindingContext}"/>
</ContentView.Behaviors>
<Grid ColumnDefinitions="Auto, *">

<Image Source="{Binding ProfilePicture}">

<Label Text="{Binding UserName}" Grid.Column="1">
</Grid>
</ContentView>
</DataTemplate>
```

0 comments on commit 5c8a036

Please sign in to comment.