2009-03-03 5 views
30

Comment puis-je définir le DataContext sur ma grille en XAML, plutôt que dans le constructeur?Silverlight - Définition de DataContext en XAML plutôt qu'en constructeur?

Voici comment je le fais dans le constructeur (LayoutRoot est la grille XAML définie dans le XAML):

this.LayoutRoot.DataContext = this.HPVM; 

Je préférerais le faire en plein XAML, mais je ne sais pas comment référence l'objet HPVM dans XAML. HPVM est une propriété publique de la classe USerControl.

Cela fonctionne bien comme indiqué ci-dessus, mais encore une fois, je veux juste savoir comment les propriétés de la classe UserControl en XAML, plutôt que de toujours avoir à le faire dans le code.

Voici tout le code correspondant:

<UserControl x:Class="SilverlightApplication1.SLHolePattern" x:Name="HolePatternsControl" 
    xmlns="http://schemas.microsoft.com/client/2007" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sys="clr-namespace:System;assembly=mscorlib"  
    xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls" 
    xmlns:local="clr-namespace:SilverlightApplication1"  
    xmlns:GeoPatterns="clr-namespace:GeoPatterns" 
    Height="700"> 


    <UserControl.Resources> 
    ... 

Et voici mon constructeur où le DataContext est actuellement fixé:

namespace SilverlightApplication1 
{ 
    public partial class SLHolePattern : UserControl, INotifyPropertyChanged 
    { 
     public HolePatternsViewModel HPVM; 

     public SLHolePattern() 
     { 
      InitializeComponent(); 

      this.HPVM=new HolePatternsViewModel(); 
      this.LayoutRoot.DataContext = this.HPVM; 
      ...more code here 
     } 

Tout fonctionne très bien, mais je veux juste apprendre à définir le DataContext en XAML, pas en code.

Répondre

24

La réponse que Chris a donnée fonctionne très bien. J'ai testé et ça a marché pour moi. Vous pouvez instancier votre classe en XAML (dans UserControl.Resources) et puis lier le datacontext à une ressource statique.

Code de suivi:

 

<UserControl ...> 
    <UserControl.Resources> 
     <myNS:MyClass x:Name="TheContext" x:Key="TheContext"></myNS:MyClass> 
    </UserControl.Resources> 
    <Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource TheContext}" > 
     <TextBlock Text="{Binding Path=Field1}"> 
     </TextBlock> 
    </Grid> 
</UserControl> 
 
+0

Si j'instancie la classe ViewModel en XAML, puis-je toujours faire référence dans le constructeur code-behind? La raison pour laquelle je demande est que je définis actuellement certaines valeurs sur le ViewModel dans le constructeur avant que le formulaire est montré à l'utilisateur. – MattSlay

+3

Oui, vous pouvez. Vous pouvez procéder comme suit: var aCustomer = this.Resources ["Cust"] en tant que client; aCustomer.Name = "abc"; – Klinger

+2

J'ai oublié d'ajouter un attribut x: Name. x: La clé fonctionne au sein de XAML et x: Name rend l'objet visible au code. – Klinger

2

essayer quelque chose comme ça .....

<Grid DataContext="{Binding Path=HPVM}"> 
</Grid> 

où HPVM est membre du public de cette -> votre formulaire etc.

Créer l'instance de votre classe dans le XAML, par ajouter quelque chose comme ceci à votre section des ressources .... (ne pas oublier d'ajouter votre espace de noms xmlns)

<my:bogart x:Key="franken"/> 

puis, lier le contexte de données à la ressource statique que vous venez d'ajouter ....

<Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource franken}"> 
    <TextBox Background="Red" Foreground="White" Text="{Binding Path=sum}" /> 
</Grid> 
+0

Ne fonctionne pas. Il doit y avoir un chemin qui indique en quelque sorte où HPVM est. dans la méthode du code, ce que le "ceci". la partie fait. HPVM est une propriété de la classe. Je ne peux pas trouver la bonne manière de référencer la classe instanciée pour arriver à HPVM. – MattSlay

+0

J'ai ajouté plus de code dans la question originale. – MattSlay

+0

Le deuxième exemple de code fonctionne, mais * crée * l'objet en XAML. Il n'aborde toujours pas l'accès aux instances d'objets créées par le constructeur à partir de XAML. Le mieux que je puisse dire ne peut être fait. Vous devez définir DataContext à partir du code si l'objet est créé dans le code. – MattSlay

0

Ceci n'est pas possible (il est possible dans WPF avec {Binding RelativeSource={RelativeSource Self}}, mais Silverlight est plus limité.

Vous devez le faire par le biais du code.

6
<UserControl.DataContext> 
    <vm:ThisUCViewModel /> 
</UserControl.DataContext> 
10

La monstruosité suivante fonctionne dans Silverlight 4

<UserControl 
    DataContext="{Binding HPVM, RelativeSource={RelativeSource Self}}"> 
+2

Je viens de vomir un peu, dans ma bouche. – Cheeso

1

Dans Silverlight 4, je suis en mesure d'obtenir ce travail en procédant comme suit:

Attribuez un x à la commande Page/UserControl: Name = "myPage"

Dans la liaison de contrôle, utilisez la syntaxe normale d'enchères d'élément.Dans mon cas, je veux lier à une collection observable des objets dans mon code derrière ma propriété ItemsSource:

<ComboBox 
    ItemsSource={Binding ElementName=myPage, Path=MyObservableObjectList, Mode=TwoWay} 

Je ne l'ai pas essayé avec DataContext mais sachez que vous pouvez faire un élément à liaison pour DataContext que je Faites cela pour les Grilles dont le contexte est basé sur l'élément sélectionné d'une autre liste déroulante sur la page.

+0

Brillant! Cela a certainement arrangé ça pour moi. Merci beaucoup. – SGarratt

0
<UserControl.Resources> 
    <ResourceDictionary> 
    <vm:YourModelx:Key="myModel"/> 
    </ResourceDictionary> 
</UserControl.Resources> 
<UserControl.DataContext> 
    <Binding Source="{StaticResource myModel}"/> 
</UserControl.DataContext> 
+0

Vous avez juste besoin d'ajouter Jacfay

Questions connexes