Xamarin.Forms Associazioni relative

Download Sample Scaricare l'esempio

Le associazioni relative consentono di impostare l'origine dell'associazione in relazione alla posizione della destinazione di associazione. Vengono creati con l'estensione RelativeSource di markup e impostati come Source proprietà di un'espressione di associazione.

L'estensione RelativeSource di markup è supportata dalla RelativeSourceExtension classe , che definisce le proprietà seguenti:

  • Mode, di tipo RelativeBindingSourceMode, descrive la posizione dell'origine dell'associazione rispetto alla posizione della destinazione di associazione.
  • AncestorLevel, di tipo int, un livello predecessore facoltativo da cercare, quando la Mode proprietà è FindAncestor. Oggetto AncestorLevel di n ignora le n-1 istanze di AncestorType.
  • AncestorType, di tipo Type, il tipo di predecessore da cercare, quando la Mode proprietà è FindAncestor.

Nota

Il parser XAML consente di abbreviatare la RelativeSourceExtension classe come RelativeSource.

La Mode proprietà deve essere impostata su uno dei membri dell'enumerazione RelativeBindingSourceMode :

  • TemplatedParent indica l'elemento a cui viene applicato il modello in cui è presente l'elemento associato. Per altre informazioni, vedere Associare a un elemento padre basato su modelli.
  • Self indica l'elemento in cui viene impostata l'associazione, consentendo di associare una proprietà di tale elemento a un'altra proprietà sullo stesso elemento. Per altre informazioni, vedere Associare a se stessi.
  • FindAncestor indica il predecessore nella struttura ad albero visuale dell'elemento associato. Questa modalità deve essere utilizzata per eseguire l'associazione a un controllo predecessore rappresentato dalla AncestorType proprietà . Per altre informazioni, vedere Associare a un predecessore.
  • FindAncestorBindingContext indica l'oggetto BindingContext del predecessore nella struttura ad albero visuale dell'elemento associato. Questa modalità deve essere utilizzata per eseguire l'associazione BindingContext a di un predecessore rappresentato dalla AncestorType proprietà . Per altre informazioni, vedere Associare a un predecessore.

La Mode proprietà è la proprietà content della RelativeSourceExtension classe . Pertanto, per le espressioni di markup XAML espresse con parentesi graffe, è possibile eliminare la Mode= parte dell'espressione.

Per altre informazioni sulle Xamarin.Forms estensioni di markup, vedi Estensioni di markup XAML.

Associare a se stessi

La Self modalità di associazione relativa viene utilizzata per associare una proprietà di un elemento a un'altra proprietà nello stesso elemento:

<BoxView Color="Red"
         WidthRequest="200"
         HeightRequest="{Binding Source={RelativeSource Self}, Path=WidthRequest}"
         HorizontalOptions="Center" />

In questo esempio la BoxView proprietà viene impostata WidthRequest su una dimensione fissa e la HeightRequest proprietà viene associata alla WidthRequest proprietà . Pertanto, entrambe le proprietà sono uguali e quindi viene disegnato un quadrato:

Screenshot of a Self mode relative binding, on iOS and Android

Importante

Quando si associa una proprietà di un elemento a un'altra proprietà sullo stesso elemento, le proprietà devono essere dello stesso tipo. In alternativa, è possibile specificare un convertitore nell'associazione per convertire il valore.

Un uso comune di questa modalità di associazione è l'impostazione di BindingContext un oggetto su una proprietà su se stessa. Il codice seguente illustra un esempio di questo:

<ContentPage ...
             BindingContext="{Binding Source={RelativeSource Self}, Path=DefaultViewModel}">
    <StackLayout>
        <ListView ItemsSource="{Binding Employees}">
            ...
        </ListView>
    </StackLayout>
</ContentPage>

In questo esempio, la BindingContext proprietà della pagina viene impostata sulla DefaultViewModel proprietà di se stessa. Questa proprietà viene definita nel file code-behind per la pagina e fornisce un'istanza del modello di visualizzazione. Viene ListView associato alla Employees proprietà del modello di visualizzazione.

Eseguire l'associazione a un predecessore

Le FindAncestor modalità di associazione relative e FindAncestorBindingContext vengono usate per eseguire il binding agli elementi padre, di un determinato tipo, nella struttura ad albero visuale. La FindAncestor modalità viene utilizzata per eseguire l'associazione a un elemento padre, che deriva dal Element tipo . La FindAncestorBindingContext modalità viene utilizzata per eseguire l'associazione all'oggetto BindingContext di un elemento padre.

Avviso

La AncestorType proprietà deve essere impostata su un Type oggetto quando si utilizzano le FindAncestor modalità di associazione relative e FindAncestorBindingContext , in caso contrario viene generata un'eccezione XamlParseException .

Se la Mode proprietà non è impostata in modo esplicito, impostare la AncestorType proprietà su un tipo che deriva da Element imposta in modo implicito la Mode proprietà su FindAncestor. Analogamente, l'impostazione della AncestorType proprietà su un tipo che non deriva da Element imposta in modo implicito la Mode proprietà su FindAncestorBindingContext.

Nota

Le associazioni relative che usano la FindAncestorBindingContext modalità verranno riapplicate quando l'oggetto BindingContext di qualsiasi predecessore cambia.

Il codice XAML seguente mostra un esempio in cui la Mode proprietà verrà impostata in modo implicito su FindAncestorBindingContext:

<ContentPage ...
             BindingContext="{Binding Source={RelativeSource Self}, Path=DefaultViewModel}">
    <StackLayout>
        <ListView ItemsSource="{Binding Employees}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Horizontal">
                            <Label Text="{Binding Fullname}"
                                   VerticalOptions="Center" />
                            <Button Text="Delete"
                                    Command="{Binding Source={RelativeSource AncestorType={x:Type local:PeopleViewModel}}, Path=DeleteEmployeeCommand}"
                                    CommandParameter="{Binding}"
                                    HorizontalOptions="EndAndExpand" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

In questo esempio, la BindingContext proprietà della pagina viene impostata sulla DefaultViewModel proprietà di se stessa. Questa proprietà viene definita nel file code-behind per la pagina e fornisce un'istanza del modello di visualizzazione. Viene ListView associato alla Employees proprietà del modello di visualizzazione. L'oggetto DataTemplate, che definisce l'aspetto di ogni elemento nell'oggetto ListView, contiene un oggetto Button. La proprietà del Command pulsante è associata all'oggetto DeleteEmployeeCommand nel modello di visualizzazione padre. Toccando un Button utente viene eliminato un dipendente:

Screenshot of a FindAncestor mode relative binding, on iOS and Android

Inoltre, la proprietà facoltativa AncestorLevel può aiutare a disambiguare la ricerca predecessore negli scenari in cui è possibile che nella struttura ad albero visuale siano presenti più predecessori di quel tipo:

<Label Text="{Binding Source={RelativeSource AncestorType={x:Type Entry}, AncestorLevel=2}, Path=Text}" />

In questo esempio la Label.Text proprietà viene associata alla Text proprietà del secondo Entry rilevato sul percorso verso l'alto, a partire dall'elemento di destinazione dell'associazione.

Nota

La AncestorLevel proprietà deve essere impostata su 1 per trovare il predecessore più vicino all'elemento di destinazione dell'associazione.

Eseguire l'associazione a un elemento padre basato su modelli

La TemplatedParent modalità di associazione relativa viene usata per eseguire il binding dall'interno di un modello di controllo all'istanza dell'oggetto di runtime a cui viene applicato il modello (noto come padre basato su modelli). Questa modalità è applicabile solo se l'associazione relativa si trova all'interno di un modello di controllo ed è simile all'impostazione di un oggetto TemplateBinding.

Il codice XAML seguente mostra un esempio della TemplatedParent modalità di associazione relativa:

<ContentPage ...>
    <ContentPage.Resources>
        <ControlTemplate x:Key="CardViewControlTemplate">
            <Frame BindingContext="{Binding Source={RelativeSource TemplatedParent}}"
                   BackgroundColor="{Binding CardColor}"
                   BorderColor="{Binding BorderColor}"
                   ...>
                <Grid>
                    ...
                    <Label Text="{Binding CardTitle}"
                           ... />
                    <BoxView BackgroundColor="{Binding BorderColor}"
                             ... />
                    <Label Text="{Binding CardDescription}"
                           ... />
                </Grid>
            </Frame>
        </ControlTemplate>
    </ContentPage.Resources>
    <StackLayout>        
        <controls:CardView BorderColor="DarkGray"
                           CardTitle="John Doe"
                           CardDescription="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla elit dolor, convallis non interdum."
                           IconBackgroundColor="SlateGray"
                           IconImageSource="user.png"
                           ControlTemplate="{StaticResource CardViewControlTemplate}" />
        <controls:CardView BorderColor="DarkGray"
                           CardTitle="Jane Doe"
                           CardDescription="Phasellus eu convallis mi. In tempus augue eu dignissim fermentum. Morbi ut lacus vitae eros lacinia."
                           IconBackgroundColor="SlateGray"
                           IconImageSource="user.png"
                           ControlTemplate="{StaticResource CardViewControlTemplate}" />
        <controls:CardView BorderColor="DarkGray"
                           CardTitle="Xamarin Monkey"
                           CardDescription="Aliquam sagittis, odio lacinia fermentum dictum, mi erat scelerisque erat, quis aliquet arcu."
                           IconBackgroundColor="SlateGray"
                           IconImageSource="user.png"
                           ControlTemplate="{StaticResource CardViewControlTemplate}" />
    </StackLayout>
</ContentPage>

In questo esempio, , Frameche è l'elemento radice di , ha il relativo BindingContext set sull'istanza dell'oggetto ControlTemplateruntime a cui viene applicato il modello. Di conseguenza, e Frame i relativi elementi figlio risolvono le espressioni di associazione rispetto alle proprietà di ogni CardView oggetto:

Screenshot of a TemplatedParent mode relative binding, on iOS and Android

Per altre informazioni sui modelli di controllo, vedere Xamarin.Forms Modelli di controllo.