Condividi tramite


Comportamenti

Browse sample. Esplorare l'esempio

I comportamenti dell'interfaccia utente dell'app multipiattaforma .NET (.NET MAUI) consentono di aggiungere funzionalità ai controlli dell'interfaccia utente senza doverli sottoclassare. La funzionalità viene invece implementata in una classe di comportamento e associata al controllo come se fosse parte del controllo stesso.

I comportamenti consentono di implementare il codice che normalmente dovrebbe essere scritto come code-behind, poiché interagisce direttamente con l'API del controllo in modo tale da poter essere associato concisamente al controllo e inserito nel pacchetto per essere riutilizzato in più di un'applicazione. Possono essere usati per offrire un'ampia gamma di funzionalità ai controlli, ad esempio:

  • Aggiunta di un validator del messaggio di posta elettronica a un Entry.
  • Creazione di un controllo classificazione tramite un riconoscimento del movimento di tocco.
  • Controllo di un'animazione.

.NET MAUI supporta tre diversi tipi di comportamenti:

  • I comportamenti associati sono classi static con una o più proprietà associate. Per altre informazioni sui comportamenti associati, vedere Comportamenti associati.
  • I comportamenti MAUI di .NET sono classi che derivano dalla Behavior classe o Behavior<T> , dove T è il tipo del controllo a cui applicare il comportamento. Per altre informazioni, vedere Comportamenti MAUI di .NET.
  • I comportamenti della piattaforma sono classi che derivano dalla PlatformBehavior<TView> classe o PlatformBehavior<TView,TPlatformView> . Questi comportamenti possono rispondere a condizioni ed eventi arbitrari su un controllo nativo. Per altre informazioni, vedere Comportamenti della piattaforma.

Comportamenti associati

I comportamenti associati sono classi statiche con una o più proprietà associate. Le proprietà associate sono un tipo speciale di proprietà associabili. Sono definite in una classe ma associate ad altri oggetti. Sono riconoscibili in XAML perché si presentano come attributi che contengono una classe e un nome di proprietà separati da un punto. Per altre informazioni sulle proprietà associate, vedere Proprietà associate.

Una proprietà associata può definire un delegato propertyChanged che verrà eseguito quando cambia il valore della proprietà, ad esempio quando la proprietà è impostata su un controllo. Quando viene eseguito, il delegato propertyChanged passa un riferimento al controllo a cui è associato e ai parametri che contengono i valori vecchi e nuovi della proprietà. Questo delegato può essere utilizzato per aggiungere nuove funzionalità al controllo a cui la proprietà è associata modificando il riferimento con cui viene passato, come indicato di seguito:

  1. Il delegato propertyChanged esegue il cast del riferimento del controllo, ricevuto come BindableObject, convertendolo nel tipo di controllo che il comportamento è progettato per migliorare.
  2. Il delegato propertyChanged modifica le proprietà del controllo, chiama i metodi del controllo o registra i gestori di eventi per gli eventi esposti dal controllo allo scopo di implementare le funzionalità del comportamento di base.

Avviso

I comportamenti associati vengono definiti in una static classe, con static proprietà e metodi. Ciò rende difficile creare comportamenti associati che presentano uno stato.

Creare un comportamento associato

Un comportamento associato può essere implementato creando una classe statica contenente una proprietà associata che specifica un propertyChanged delegato.

L'esempio seguente mostra la AttachedNumericValidationBehavior classe , che evidenzia il valore immesso dall'utente in un Entry controllo in rosso se non è un oggetto double:

public static class AttachedNumericValidationBehavior
{
    public static readonly BindableProperty AttachBehaviorProperty =
        BindableProperty.CreateAttached("AttachBehavior", typeof(bool), typeof(AttachedNumericValidationBehavior), false, propertyChanged: OnAttachBehaviorChanged);

    public static bool GetAttachBehavior(BindableObject view)
    {
        return (bool)view.GetValue(AttachBehaviorProperty);
    }

    public static void SetAttachBehavior(BindableObject view, bool value)
    {
        view.SetValue(AttachBehaviorProperty, value);
    }

    static void OnAttachBehaviorChanged(BindableObject view, object oldValue, object newValue)
    {
        Entry entry = view as Entry;
        if (entry == null)
        {
            return;
        }

        bool attachBehavior = (bool)newValue;
        if (attachBehavior)
        {
            entry.TextChanged += OnEntryTextChanged;
        }
        else
        {
            entry.TextChanged -= OnEntryTextChanged;
        }
    }

    static void OnEntryTextChanged(object sender, TextChangedEventArgs args)
    {
        double result;
        bool isValid = double.TryParse(args.NewTextValue, out result);
        ((Entry)sender).TextColor = isValid ? Colors.Black : Colors.Red;
    }
}

In questo esempio la AttachedNumericValidationBehavior classe contiene una proprietà associata denominata AttachBehavior con un static getter e un setter, che controlla l'aggiunta o la rimozione del comportamento al controllo a cui verrà associato. Tale proprietà associata registra il metodo OnAttachBehaviorChanged che verrà eseguito quando cambia il valore della proprietà. Questo metodo registra, o annulla la registrazione di, un gestore eventi per l'evento TextChanged, in base al valore della proprietà associata AttachBehavior. La funzionalità principale del comportamento viene fornita dal OnEntryTextChanged metodo , che analizza il valore immesso in Entry e imposta la TextColor proprietà su rosso se il valore non è .double

Utilizzare un comportamento associato

Un comportamento associato può essere utilizzato impostando la relativa proprietà associata nel controllo di destinazione.

Nell'esempio seguente viene illustrato l'utilizzo della AttachedNumericValidationBehavior classe in un oggetto Entry aggiungendo la AttachBehavior proprietà associata a Entry:


<ContentPage ...
             xmlns:local="clr-namespace:BehaviorsDemos">
    <Entry Placeholder="Enter a System.Double" local:AttachedNumericValidationBehavior.AttachBehavior="true" />
</ContentPage>

Il codice C# equivalente per Entry è visualizzato nell'esempio seguente:

Entry entry = new Entry { Placeholder = "Enter a System.Double" };
AttachedNumericValidationBehavior.SetAttachBehavior(entry, true);

Lo screenshot seguente mostra il comportamento associato che risponde all'input non valido:

Screenshot of attached behavior responding to invalid input

Nota

I comportamenti associati vengono scritti per un tipo di controllo specifico, o per una superclasse che è possibile applicare a molti controlli, e devono essere aggiunti solo a controlli compatibili.

Rimuovere un comportamento associato

La AttachedNumericValidationBehavior classe può essere rimossa da un controllo impostando la AttachBehavior proprietà associata su false:

<Entry Placeholder="Enter a System.Double" local:AttachedNumericValidationBehavior.AttachBehavior="false" />

In fase di esecuzione, il metodo OnAttachBehaviorChanged sarà eseguito quando il valore della proprietà associata AttachBehavior è impostato su false. Il OnAttachBehaviorChanged metodo registrerà quindi il gestore eventi per l'evento TextChanged , assicurandosi che il comportamento non venga eseguito durante l'interazione con il controllo.

Comportamenti MAUI di .NET

I comportamenti MAUI di .NET vengono creati derivando dalla Behavior classe o Behavior<T> .

Il processo di creazione di un comportamento MAUI .NET è il seguente:

  1. Creare una classe che erediti dalla classe Behavior o dalla classe Behavior<T>, dove T è il tipo di controllo al quale deve essere applicato il comportamento.
  2. Eseguire l'override del metodo OnAttachedTo per eseguire le configurazioni richieste.
  3. Eseguire l'override del metodo OnDetachingFrom per eseguire le operazioni di pulizia richieste.
  4. Implementare le funzionalità principali del comportamento.

Ciò comporta la struttura illustrata nell'esempio seguente:

public class MyBehavior : Behavior<View>
{
    protected override void OnAttachedTo(View bindable)
    {
        base.OnAttachedTo(bindable);
        // Perform setup
    }

    protected override void OnDetachingFrom(View bindable)
    {
        base.OnDetachingFrom(bindable);
        // Perform clean up
    }

    // Behavior implementation
}

Il OnAttachedTo metodo viene chiamato immediatamente dopo che il comportamento è associato a un controllo . Questo metodo riceve un riferimento al controllo a cui è associato e può essere utilizzato per registrare i gestori eventi o per eseguire altre impostazioni necessarie per supportare la funzionalità del comportamento. Ad esempio, eseguire una sottoscrizione a un evento in un controllo. La funzionalità del comportamento verrebbe quindi implementata nel gestore eventi per l'evento.

Il OnDetachingFrom metodo viene chiamato quando il comportamento viene rimosso dal controllo . Questo metodo riceve un riferimento al controllo a cui è associato e serve per eseguire le operazioni di pulizia necessarie. Ad esempio, annullare la sottoscrizione da un evento in un controllo per evitare perdite di memoria.

Il comportamento può quindi essere utilizzato collegandolo alla Behaviors raccolta del controllo .

Creare un comportamento MAUI .NET

Un comportamento MAUI .NET può essere implementato creando una classe che deriva dalla Behavior classe o Behavior<T> ed eseguendo l'override dei OnAttachedTo metodi e OnDetachingFrom .

L'esempio seguente mostra la NumericValidationBehavior classe , che evidenzia il valore immesso dall'utente in un Entry controllo in rosso se non è un oggetto double:

public class NumericValidationBehavior : Behavior<Entry>
{
    protected override void OnAttachedTo(Entry entry)
    {
        entry.TextChanged += OnEntryTextChanged;
        base.OnAttachedTo(entry);
    }

    protected override void OnDetachingFrom(Entry entry)
    {
        entry.TextChanged -= OnEntryTextChanged;
        base.OnDetachingFrom(entry);
    }

    void OnEntryTextChanged(object sender, TextChangedEventArgs args)
    {
        double result;
        bool isValid = double.TryParse(args.NewTextValue, out result);
        ((Entry)sender).TextColor = isValid ? Colors.Black : Colors.Red;
    }
}

In questo esempio la NumericValidationBehavior classe deriva dalla Behavior<T> classe , dove T è un Entryoggetto . Il metodo OnAttachedTo registra un gestore eventi per l'evento TextChanged, con il metodo OnDetachingFrom che annulla la registrazione dell'evento TextChangedper evitare perdite di memoria. La funzionalità principale del comportamento viene fornita dal OnEntryTextChanged metodo , che analizza il valore immesso in Entry e imposta la TextColor proprietà su rosso se il valore non è .double

Importante

.NET MAUI non imposta l'oggetto BindingContext di un comportamento, perché i comportamenti possono essere condivisi e applicati a più controlli tramite stili.

Utilizzare un comportamento MAUI .NET

Ogni controllo MAUI .NET dispone di una Behaviors raccolta a cui è possibile aggiungere uno o più comportamenti:

<Entry Placeholder="Enter a System.Double">
    <Entry.Behaviors>
        <local:NumericValidationBehavior />
    </Entry.Behaviors>
</Entry>

Il codice C# equivalente per Entry è visualizzato nell'esempio seguente:

Entry entry = new Entry { Placeholder = "Enter a System.Double" };
entry.Behaviors.Add(new NumericValidationBehavior());

Lo screenshot seguente mostra il comportamento maUI di .NET che risponde all'input non valido:

Screenshot of .NET MAUI behavior responding to invalid input

Avviso

I comportamenti MAUI di .NET vengono scritti per un tipo di controllo specifico (o una superclasse che può essere applicata a molti controlli) e devono essere aggiunti solo a un controllo compatibile. Se si tenta di associare un comportamento MAUI .NET a un controllo incompatibile, verrà generata un'eccezione.

Utilizzare un comportamento MAUI .NET con uno stile

I comportamenti MAUI di .NET possono essere utilizzati da uno stile esplicito o implicito. Tuttavia, non è possibile creare uno stile che imposti la proprietà Behaviors di un controllo perché la proprietà è di sola lettura. La soluzione consiste nell'aggiungere una proprietà associata alla classe di comportamento che controlli l'aggiunta del comportamento o la sua rimozione. Passaggi del processo:

  1. Aggiungere una proprietà associata alla classe di comportamento che verrà utilizzata per controllare l'aggiunta o la rimozione del comportamento al controllo a cui verrà associato il comportamento. Assicurarsi che la proprietà associata registri un delegato propertyChanged che verrà eseguito quando cambia il valore della proprietà.
  2. Creare un getter e un setter static per la proprietà associata.
  3. Implementare la logica nel delegato propertyChanged per aggiungere e rimuovere il comportamento.

Nell'esempio seguente viene illustrata la NumericValidationStyleBehavior classe , con una proprietà associata che controlla l'aggiunta e la rimozione del comportamento:

public class NumericValidationStyleBehavior : Behavior<Entry>
{
    public static readonly BindableProperty AttachBehaviorProperty =
        BindableProperty.CreateAttached("AttachBehavior", typeof(bool), typeof(NumericValidationStyleBehavior), false, propertyChanged: OnAttachBehaviorChanged);

    public static bool GetAttachBehavior(BindableObject view)
    {
        return (bool)view.GetValue(AttachBehaviorProperty);
    }

    public static void SetAttachBehavior(BindableObject view, bool value)
    {
        view.SetValue(AttachBehaviorProperty, value);
    }

    static void OnAttachBehaviorChanged(BindableObject view, object oldValue, object newValue)
    {
        Entry entry = view as Entry;
        if (entry == null)
        {
            return;
        }

        bool attachBehavior = (bool)newValue;
        if (attachBehavior)
        {
            entry.Behaviors.Add(new NumericValidationStyleBehavior());
        }
        else
        {
            Behavior toRemove = entry.Behaviors.FirstOrDefault(b => b is NumericValidationStyleBehavior);
            if (toRemove != null)
            {
                entry.Behaviors.Remove(toRemove);
            }
        }
    }

    protected override void OnAttachedTo(Entry entry)
    {
        entry.TextChanged += OnEntryTextChanged;
        base.OnAttachedTo(entry);
    }

    protected override void OnDetachingFrom(Entry entry)
    {
        entry.TextChanged -= OnEntryTextChanged;
        base.OnDetachingFrom(entry);
    }

    void OnEntryTextChanged(object sender, TextChangedEventArgs args)
    {
        double result;
        bool isValid = double.TryParse(args.NewTextValue, out result);
        ((Entry)sender).TextColor = isValid ? Colors.Black : Colors.Red;
    }
}

In questo esempio la NumericValidationStyleBehavior classe contiene una proprietà associata denominata AttachBehavior con un static getter e un setter, che controlla l'aggiunta o la rimozione del comportamento al controllo a cui verrà associato. Tale proprietà associata registra il metodo OnAttachBehaviorChanged che verrà eseguito quando cambia il valore della proprietà. Questo metodo aggiunge il comportamento al controllo o lo rimuove da esso in base al valore della proprietà AttachBehavior associata.

L'esempio di codice riportato di seguito illustra uno stile esplicito per il NumericValidationStyleBehavior che usa la proprietà associata AttachBehavior e che può essere applicato ai controlli Entry:

<Style x:Key="NumericValidationStyle" TargetType="Entry">
    <Style.Setters>
        <Setter Property="local:NumericValidationStyleBehavior.AttachBehavior" Value="true" />
    </Style.Setters>
</Style>

L'oggetto Style può essere applicato a un Entry oggetto impostando la relativa Style proprietà sullo stile utilizzando l'estensione di StaticResource markup:

<Entry Placeholder="Enter a System.Double" Style="{StaticResource NumericValidationStyle}">

Per altre informazioni sugli stili, vedere Stili.

Nota

Sebbene sia possibile aggiungere proprietà associabili a un comportamento impostato o sottoposto a query in XAML, se si creano comportamenti con stato, questi non devono essere condivisi tra i controlli tramite uno Style in un oggetto ResourceDictionary.

Rimuovere un comportamento MAUI .NET

Il OnDetachingFrom metodo viene chiamato quando un comportamento viene rimosso da un controllo e viene usato per eseguire qualsiasi pulizia necessaria, ad esempio annullare la sottoscrizione da un evento per evitare una perdita di memoria. Tuttavia, i comportamenti non vengono rimossi in modo implicito dai controlli a meno che la raccolta del Behaviors controllo non venga modificata dal Remove metodo o Clear :

Behavior toRemove = entry.Behaviors.FirstOrDefault(b => b is NumericValidationStyleBehavior);
if (toRemove != null)
{
    entry.Behaviors.Remove(toRemove);
}

In alternativa, la raccolta del Behaviors controllo può essere cancellata:

entry.Behaviors.Clear();

Nota

I comportamenti MAUI di .NET non vengono rimossi in modo implicito dai controlli quando le pagine vengono estratte dallo stack di navigazione. Devono pertanto essere rimossi esplicitamente prima che le pagine diventino esterne all'ambito.

Comportamenti della piattaforma

I comportamenti della piattaforma vengono creati derivando dalla PlatformBehavior<TView> classe o PlatformBehavior<TView,TPlatformView> . Rispondono a condizioni ed eventi arbitrari su un controllo nativo.

Un comportamento della piattaforma può essere implementato tramite la compilazione condizionale o le classi parziali. L'approccio adottato in questo caso consiste nell'usare classi parziali, in cui un comportamento della piattaforma è in genere costituito da una classe parziale multipiattaforma che definisce l'API dei comportamenti e da una classe parziale nativa che implementa il comportamento in ogni piattaforma. In fase di compilazione, il multitargeting combina le classi parziali per compilare il comportamento della piattaforma in ogni piattaforma.

Il processo di creazione di un comportamento della piattaforma è il seguente:

  1. Creare una classe parziale multipiattaforma che definisce l'API per il comportamento della piattaforma.

  2. Creare una classe parziale nativa in ogni piattaforma per cui viene creata l'app, con lo stesso nome della classe parziale multipiattaforma. Questa classe parziale nativa deve ereditare dalla PlatformBehavior<TView> classe o PlatformBehavior<TView,TPlatformView> , dove TView è il controllo multipiattaforma a cui deve essere applicato il comportamento ed TPlatformView è la visualizzazione nativa che implementa il controllo multipiattaforma in una determinata piattaforma.

    Nota

    Anche se è necessario creare una classe parziale nativa in ogni piattaforma per cui viene creata l'app, non è necessario implementare la funzionalità del comportamento della piattaforma in ogni piattaforma. Ad esempio, è possibile creare un comportamento della piattaforma che modifica lo spessore del bordo di un controllo nativo in alcune piattaforme, ma non tutte.

  3. In ogni classe parziale nativa che è necessario implementare il comportamento della piattaforma è necessario:

    1. Eseguire l'override del OnAttachedTo metodo per eseguire qualsiasi installazione.
    2. Eseguire l'override del OnDetachedFrom metodo per eseguire qualsiasi pulizia.
    3. Implementare la funzionalità di base del comportamento della piattaforma.

Il comportamento può quindi essere utilizzato collegandolo alla Behaviors raccolta del controllo .

Creare un comportamento della piattaforma

Per creare un comportamento della piattaforma, è prima necessario creare una classe parziale multipiattaforma che definisce l'API per il comportamento della piattaforma:

namespace BehaviorsDemos
{
    public partial class TintColorBehavior
    {
        public static readonly BindableProperty TintColorProperty =
            BindableProperty.Create(nameof(TintColor), typeof(Color), typeof(TintColorBehavior));

        public Color TintColor
        {
            get => (Color)GetValue(TintColorProperty);
            set => SetValue(TintColorProperty, value);
        }
    }
}

Il comportamento della piattaforma è una classe parziale la cui implementazione verrà completata in ogni piattaforma necessaria con una classe parziale aggiuntiva che usa lo stesso nome. In questo esempio, la TintColorBehavior classe definisce una singola proprietà associabile, TintColor, che tinterà un'immagine con il colore specificato.

Dopo aver creato la classe parziale multipiattaforma, è necessario creare una classe parziale nativa in ogni piattaforma per cui si compila l'app. A tale scopo, è possibile aggiungere classi parziali alle cartelle figlio necessarie della cartella Piattaforme :

Screenshot of the native partial classes for a platform behavior.

In alternativa, è possibile configurare il progetto per supportare multitargeting basato su nomi file o multitargeting basato su cartelle o entrambi. Per altre informazioni sul multitargeting, vedere Configurare multitargeting.

Le classi parziali native devono ereditare dalla PlatformBehavior<TView> classe o dalla PlatformBehavior<TView,TPlatformView> classe , dove TView è il controllo multipiattaforma a cui applicare il comportamento ed TPlatformView è la visualizzazione nativa che implementa il controllo multipiattaforma in una determinata piattaforma. In ogni classe parziale nativa che è necessario implementare il comportamento della piattaforma, è necessario eseguire l'override del OnAttachedTo metodo e del OnDetachedFrom metodo e implementare le funzionalità principali del comportamento della piattaforma.

Il OnAttachedTo metodo viene chiamato immediatamente dopo che il comportamento della piattaforma è collegato a un controllo multipiattaforma. Il metodo riceve un riferimento al controllo multipiattaforma a cui è collegato e, facoltativamente, un riferimento al controllo nativo che implementa il controllo multipiattaforma. Il metodo può essere usato per registrare i gestori eventi o eseguire altre configurazioni necessarie per supportare la funzionalità del comportamento della piattaforma. Ad esempio, eseguire una sottoscrizione a un evento in un controllo. La funzionalità del comportamento verrebbe quindi implementata nel gestore eventi per l'evento.

Il OnDetachedFrom metodo viene chiamato quando il comportamento viene rimosso dal controllo multipiattaforma. Il metodo riceve un riferimento al controllo a cui è collegato e, facoltativamente, un riferimento al controllo nativo che implementa il controllo multipiattaforma. Il metodo deve essere usato per eseguire le operazioni di pulizia necessarie. Ad esempio, annullare la sottoscrizione da un evento in un controllo per evitare perdite di memoria.

Importante

Le classi parziali devono trovarsi nello stesso spazio dei nomi e usare nomi identici.

L'esempio seguente mostra la TintColorBehavior classe parziale per Android, che tinta un'immagine con un colore specificato:

using Android.Graphics;
using Android.Widget;
using Microsoft.Maui.Platform;
using Color = Microsoft.Maui.Graphics.Color;

namespace BehaviorsDemos
{
    public partial class TintColorBehavior : PlatformBehavior<Image, ImageView>
    {
        protected override void OnAttachedTo(Image bindable, ImageView platformView)
        {
            base.OnAttachedTo(bindable, platformView);

            if (bindable is null)
                return;
            if (TintColor is null)
                ClearColor(platformView);
            else
                ApplyColor(platformView, TintColor);
        }

        protected override void OnDetachedFrom(Image bindable, ImageView platformView)
        {
            base.OnDetachedFrom(bindable, platformView);

            if (bindable is null)
                return;
            ClearColor(platformView);
        }

        void ApplyColor(ImageView imageView, Color color)
        {
            imageView.SetColorFilter(new PorterDuffColorFilter(color.ToPlatform(), PorterDuff.Mode.SrcIn ?? throw new NullReferenceException()));
        }

        void ClearColor(ImageView imageView)
        {
            imageView.ClearColorFilter();
        }
    }
}

In questo esempio la TintColorBehavior classe deriva dalla PlatformBehavior<TView,TPlatformView> classe , dove TView è un Image oggetto e TPlatformView è .ImageView OnAttachedTo Applica il colore della tinta all'immagine, purché la TintColor proprietà abbia un valore. Il OnDetachedFrom metodo rimuove il colore della tinta dall'immagine.

È necessario aggiungere una classe parziale nativa in ogni piattaforma per cui si compila l'app. Tuttavia, è possibile rendere no-OP la classe parziale nativa, se il comportamento della piattaforma non è necessario in una piattaforma specifica. A tale scopo, è possibile fornire una classe vuota:

using Microsoft.UI.Xaml;

namespace BehaviorsDemos
{
    public partial class TintColorBehavior : PlatformBehavior<Image, FrameworkElement>
    {
        // NO-OP on Windows
    }
}

Importante

.NET MAUI non imposta l'oggetto BindingContext di un comportamento della piattaforma.

Utilizzare un comportamento della piattaforma

Ogni controllo MAUI .NET ha una Behaviors raccolta, a cui è possibile aggiungere uno o più comportamenti della piattaforma:

<Image Source="dotnet_bot.png"
       HeightRequest="200"
       HorizontalOptions="Center">
    <Image.Behaviors>
        <local:TintColorBehavior TintColor="Red" />
    </Image.Behaviors>
</Image>

L'equivalente Image in C# è illustrato nell'esempio seguente:

Image image = new Image { Source = "dotnet_bot.png", HeightRequest = 200, HorizontalOptions = LayoutOptions.Center };
image.Behaviors.Add(new TintColorBehavior());

Lo screenshot seguente mostra il comportamento della piattaforma che colora un'immagine:

Screenshot of .NET MAUI platform behavior tinting an image.

Avviso

I comportamenti della piattaforma vengono scritti per un tipo di controllo specifico (o una superclasse che può essere applicata a molti controlli) e devono essere aggiunti solo a un controllo compatibile. Se si tenta di collegare un comportamento della piattaforma a un controllo incompatibile, verrà generata un'eccezione.