Associazione a UserControl DependencyProperty

Associazione a UserControl DependencyProperty

Con la seguente associazione nel tuo UserControl :

<Label Content="{Binding MyText}"/>

Non sono sicuro di come funzioni l'impostazione del testo direttamente sulla proprietà MyText. Devi impostare il DataContext sul UserControl da qualche parte perché funzioni.

Indipendentemente da ciò, questo legame è il problema:da quanto ho capito il tuo scenario, non vuoi eseguire il binding a DataContext del UserControl perché non avrà necessariamente una proprietà MyText. Vuoi associare al UserControl stesso, e in particolare il DependencyProperty hai creato. Per farlo, devi usare un RelativeSource vincolante, come il seguente:

<Label Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}, Path=MyText}"/>

Questo passerà all'albero visivo fino a MyUserControl e quindi troverà la proprietà MyText lì. Non dipenderà da DataContext , che cambierà in base a dove posizioni il UserControl .

In questo caso, local fa riferimento a uno spazio dei nomi che dovrai definire nel UserControl :

<UserControl x:Class="TestUserControBinding.MyUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:TestUserControBinding"
         ...>

E il tuo secondo esempio dovrebbe funzionare a quel punto.


C'è un malinteso su come DataContext s sono impostati. Questo sta lavorando contro di te...

Infine il legame con MyText sul controllo utente, non è vincolato al MyText del controllo proprietà di dipendenza ma al DataContext della pagina e non c'è MyText proprietà.

Mi spiego

Spiegazione Quando il controllo utente viene inserito nella tua pagina principale, eredita il DataContext del genitore dei suoi controlli (il StackPanel ). Se il DataContext del genitore non è impostato, risalirà la catena fino al StackPanel DataContext del genitore di 's (ad Infinium) fino ad arrivare al DataContext della pagina (che nel tuo esempio è impostato e valido ).

Quando esegui il binding sulla pagina principale come <local:MyUserControl MyText="{Binding Path=Text}"/> cerca Text proprietà nelle pagine principali DataContext e imposta la proprietà di dipendenza MyText a quel valore. Che è quello che ti aspetti e funziona!

Stato attuale Quindi lo stato del controllo utente nel tuo codice è questo, il suo DataContext è legato al DataContext della pagina e MyText la proprietà di dipendenza è impostata. Ma il legame del controllo interno con MyText non riesce. Perché?

Il controllo utente ha il contesto dati del genitore e stai chiedendo al controllo di associarsi a un MyText proprietà su quello contesto dei dati. Non esiste una tale proprietà e non riesce.

Risoluzione

Per eseguire il collegamento all'istanza del controllo e ottieni il valore da MyText proprietà, basta inserire un nome (un nome di elemento ) sul controllo come

<User Control x:Class="TestUserControBinding.MyUserControl"
             ...
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             x:Name="ucMyUserControl"

e quindi eseguire correttamente il percorso dell'associazione lontano dal DataContext predefinito e all'nomeelemento istanza denominata ucMyUserControl . Ad esempio:

  <Label Content="{Binding MyText, ElementName=ucMyUserControl }"/>

Nota che VS2017/2019 intellisenserà effettivamente il ElementName dopo aver denominato il controllo.

Effetto collaterale del semplice utilizzo del contesto dei dati dei genitori

Un effetto collaterale della situazione originale senza la risoluzione menzionata è che potresti semplicemente associare l'associazione del controllo utente a Text e funziona perché l'associazione è predefinita per il contesto dati della pagina. Sottile...

<User Control x:Class="TestUserControBinding.MyUserControl"
             mc:Ignorable="d" 
             d:DesignHeight="30" d:DesignWidth="100">
 <Grid>
    <Label Content="{Binding Text}"/>

Funziona e tecnicamente potresti rimuovere la proprietà di dipendenza. Se il controllo non viene utilizzato all'esterno del progetto, potrebbe essere progettato per l'associazione anche ad altre proprietà denominate senza effetti negativi.

Quindi tutti i controlli utente potrebbero diventare di fatto controlli secondari della pagina principale, come se hai appena incollato l'XAML interno nella pagina.