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.