2010-08-12 4 views
3

J'essaie de définir une liaison bidirectionnelle sur un UserControl que j'ai créé.Liaison TwoWay avec UserControl

Lorsque j'utilise le contrôle en XAML est réglé DataContext comme si ...

<uc:MyUserControl DataContext="{Binding Path=MyObject, Mode=TwoWay}" /> 

Mon contrôle utilisateur est défini comme ce qui suit ....

<UserControl x:Class="SilverlightApplication1.XText" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400"> 

    <Grid x:Name="LayoutRoot" Background="White"> 
     <TextBox x:Name="Text" Text="{Binding}"/> 

    </Grid> 
</UserControl> 

Les données sont affichées correctement, cependant si je fais je change, je voulais le mettre à jour avec la liaison TwoWay.

J'ai essayé ceci ci-dessous, mais il y a des erreurs au moment de l'exécution car aucun chemin n'est défini.

<Grid x:Name="LayoutRoot" Background="White"> 
     <TextBox x:Name="Text" Text="{Binding Mode=TwoWay}"/> 

    </Grid> 
</UserControl> 

Toutes les idées sur la façon d'obtenir le contrôle à l'intérieur du usercontrol à TwoWay se lient au DataContext?

Répondre

1

J'ai trouvé une solution qui ne nécessite pas de donner un nom au contrôle de base. Lorsque j'ai défini un nom pour UserControl de base, cela créait des problèmes pour moi lorsque j'ajoutais plusieurs instances à ma grille, car elles étaient définies sous le même nom.

C'est une combinaison de ma première réponse et de la réponse de Doug. Notez le UserControl n'a pas la propriété de nom et la zone de texte n'a pas Binding déclaré dans le XAML

XAML

<UserControl 
    x:Class="SilverlightApplication1.XText" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    d:DesignHeight="300" 
    d:DesignWidth="400"> 

    <Grid x:Name="LayoutRoot" Background="White"> 
     <TextBox x:Name="MyText"/>  
    </Grid> 
</UserControl> 

CodeBehind

public partial class XText 
{ 
    public XText() 
    { 
     InitializeComponent(); 
     MyText.SetBinding(TextBox.TextProperty, new Binding() 
     { 
      Source = this, 
      Path = new PropertyPath("Value"), 
      Mode = BindingMode.TwoWay 
     }); 
    } 


    public static DependencyProperty ValueProperty = 
     DependencyProperty.Register(
      "Value", 
      typeof(string), 
      typeof(XText), 
      new PropertyMetadata(null) 
     ); 

    public string Value 
    { 
     get { return ((string)(GetValue(ValueProperty))); } 
     set { SetValue(ValueProperty, value); } 
    } 

    ... 
} 

Lorsque vous êtes prêt à l'utiliser faire le suivant

<uc:XText Value="{Binding Path=MyObject, Mode=TwoWay}" /> 
+0

Le fragment MyText.SetBinding() est toujours un peu un hack. Je pense que vous trouverez que l'utiliser est beaucoup plus de problèmes que cela en vaut la peine. – Doug

0

Ok je pense que je suis venu avec un moyen d'obtenir ce travail ....

D'abord, je mis une propriété publique dans le code de mon UserControl derrière ...

public Binding BindingValue 
{ 
    set { this.MyTextBox.SetBinding(TextBox.TextProperty, value); } 
} 

Puis, en XAML

<uc:MyUserControl BindingValue="{Binding Path=MyObject, Mode=TwoWay}" /> 
2

Bien que votre ci-dessus (auto-réponse) réponse semble résoudre le problème, je ne peux que penser que c'est un problème de domaine du problème. J'ai du mal à penser pourquoi vous souhaitez lier directement comme ça en premier lieu, d'autant plus que cela vous donne moins de contrôle sur ce qui se passe avec les données.

Prenez les éléments suivants:

<UserControl 
    x:Class="SilverlightApplication1.XText" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    x:Name="UserControl" 
    d:DesignHeight="300" 
    d:DesignWidth="400"> 

    <Grid x:Name="LayoutRoot" Background="White"> 
     <TextBox x:Name="Text" Text="{Binding Path=Value, ElementName=UserControl, Mode=TwoWay}"/>  
    </Grid> 
</UserControl> 

Ensuite, dans le behind:

public partial class XText 
{ 
    public static DependencyProperty ValueProperty = 
     DependencyProperty.Register(
      "Value", 
      typeof(string), 
      typeof(XText), 
      new FrameworkPropertyMetadata(null) 
     ); 

    public string Value 
    { 
     get { return ((string)(base.GetValue(XText.ValueProperty))); } 
     set { base.SetValue(XText.ValueProperty, value); } 
    } 

    ... 
} 

Ensuite, lorsque vous êtes prêt à l'utiliser:

<uc:XText Value="{Binding Path=MyObject, Mode=TwoWay}" /> 

Oui, il est plus de code , mais il vous donne beaucoup plus de contrôle sur ce qui se passe avec Value à l'intérieur de votre UserControl, et rend le travail avec ce code beaucoup plus simple à l'avenir.

Pensées?

-Doug

EDIT: correction d'un typos couple.

+0

Approche intéressante, laissez-moi essayer cela. – Gabe

+0

une chose que j'ai remarqué est aléatoirement que je reçois une erreur lors de l'ajout de ce contrôle de l'utilisateur à ma grille. Si j'utilise un couple de ces contrôles utilisateur, je reçois une erreur disant "La valeur ne se situe pas dans la fourchette attendue" ... Si je continue le débogage, je reçois une erreur d'analyseur dire "UserControl existe déjà dans l'arbre" UserControl comme vous avez fait dans le ci-dessus, est-ce créer le problème? Lorsque je crée réellement l'instance de UserControl, je ne lui donne aucun nom. Mais comme vous, je lui ai donné le nom UserControl à l'intérieur du Xaml pour UserControl afin que je puisse utiliser ElementName pour lier – Gabe

+0

J'ai nommé tous mes UserControls et n'ai jamais rencontré ce problème. Lorsque vous nommez votre UserControl, il tombe uniquement dans la portée du nom du contrôle lui-même. Par conséquent, il n'aura pas de collisions de noms lorsque vous avez le même contrôle plusieurs fois sur votre page. Je ne pense pas que le problème soit lié au code que je vous ai donné, mais à votre implémentation quelque part. – Doug

Questions connexes