2009-12-07 3 views
0

J'ai une composition de classe DependencyObject qui ressemble à ce qui suit:WPF Confusion Reliure: Composite DependencyObject

public class A : DependencyObject { 
    public AB AB { get { ... } set { ... } } 
    public AB AC { get { ... } set { ... } } 
} 

public class AB : DependencyObject { 
    public string Property1 { get { ... } set { ... } } 
    public string Property2 { get { ... } set { ... } } 
    public string Property3 { get { ... } set { ... } } 
} 

public class AC : DependencyObject { 
    public string Property1 { get { ... } set { ... } } 
    public string Property2 { get { ... } set { ... } } 
} 

On A, AB et AC toutes les propriétés effectuent la GetValue typique et opérations SetValue référencement propriétés statiques par habitude. Maintenant, les classes A, AB et AC ont des UserControls AGroupBox correspondants, ABGrid, ACGrid. AGroupBox possède une propriété de classe A root, ABGrid possède une propriété de classe AB root et ACGrid possède une propriété de classe AC racine. Par exemple, ABGrid contient un contrôle TextBox dont la propriété Text est liée à la propriété 1 d'AB. J'ai vérifié cela en créant une fenêtre simple et en ayant ABGrid comme seul enfant Content de Windows et en le code derrière la définition de ABGrid.AB = new AB(); même scénario pour ACGrid.AC = new AC() ;.

Le problème est quand j'essaye de faire de même avec AGroupBox. J'essaie d'ajouter AGroupBox en tant qu'enfant unique du contenu de Windows dans XAML et de définir la propriété AGroupBox.A comme nouvelle A() {AB = nouvelle AB(), AC = nouvelle AC()}; et la liaison des contrôles échoue. AB et AC ont des valeurs par défaut pour leurs propriétés PropertyN.

Un aperçu de ce qui me manque? Y a-t-il une voie différente que je devrais suivre? Commentaire supplémentaire - Si j'ajoute une propriété de chaîne à A, (String1) et la lie à la partie Text de la GroupBox, la liaison à cette propriété fonctionne, mais pas aux propriétés AC et AB de A.

EDIT-2: par la demande de David Hay (tout le code dans l'espace de noms wpfStackOverflow):

A.cs

public class A : DependencyObject { 
    static public DependencyProperty BProperty { get; private set; } 
    static public DependencyProperty CProperty { get; private set; } 
    static public DependencyProperty PropertyProperty { get; private set; } 

    static A() { 
     BProperty = DependencyProperty.Register("B", typeof(B), typeof(A)); 
     CProperty = DependencyProperty.Register("C", typeof(C), typeof(A)); 
     PropertyProperty = DependencyProperty.Register("Property", typeof(string), typeof(A)); 
    } 

    public B B { 
     get { return (B)GetValue(BProperty); } 
     set { SetValue(BProperty, value); } 
    } 

    public C C { 
     get { return (C)GetValue(CProperty); } 
     set { SetValue(CProperty, value); } 
    } 

    public string Property { 
     get { return (string)GetValue(PropertyProperty); } 
     set { SetValue(PropertyProperty, value); } 
    } 

    public A() { 
     Property = "A's Default Value"; 
     B = new B(); 
     C = new C(); 
    } 
} 

B.cs

public class B : DependencyObject { 
    static public DependencyProperty PropertyProperty { get; private set; } 

    static B() { 
     PropertyProperty = DependencyProperty.Register("Property", typeof(string), typeof(B)); 
    } 

    public string Property { 
     get { return (string)GetValue(PropertyProperty); } 
     set { SetValue(PropertyProperty, value); } 
    } 

    public B() { 
     Property = "B's Default Value"; 
    } 
} 

C.cs

public class C : DependencyObject { 
    static public DependencyProperty PropertyProperty { get; private set; } 

    static C() { 
     PropertyProperty = DependencyProperty.Register("Property", typeof(string), typeof(C)); 
    } 

    public string Property { 
     get { return (string)GetValue(PropertyProperty); } 
     set { SetValue(PropertyProperty, value); } 
    } 

    public C() { 
     Property = "C's Default Value"; 
    } 
} 

AGroupBox.xaml

<UserControl 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:wpfStackOverflow" 
    x:Class="wpfStackOverflow.AGroupBox" 
    DataContext="{Binding RelativeSource={RelativeSource Self}, Path=A}" 
    Width="300" 
    Height="72" 
    > 
    <GroupBox Header="{Binding Property}"> 
     <StackPanel > 
      <local:BGrid B="{Binding B}"/> 
      <local:CGrid C="{Binding C}"/> 
     </StackPanel> 
    </GroupBox> 
</UserControl> 

AGroupBox.xaml.cs

public partial class AGroupBox : UserControl { 
    static public DependencyProperty AProperty { get; private set; } 

    static AGroupBox() { 
     AProperty = DependencyProperty.Register("A", typeof(A), typeof(AGroupBox)); 
    } 

    public A A { 
     get { return (A)GetValue(AProperty); } 
     set { SetValue(AProperty, value); } 
    } 

    public AGroupBox() { 
     InitializeComponent(); 
    } 
} 

BGrid.xaml

<UserControl 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Class="wpfStackOverflow.BGrid" 
    DataContext="{Binding RelativeSource={RelativeSource Self}, Path=B}" 
    > 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto"/> 
      <ColumnDefinition /> 
     </Grid.ColumnDefinitions> 

     <Label Grid.Column="0" Content="Property"/> 
     <TextBox Grid.Column="1" Text="{Binding Property}"/> 
    </Grid> 
</UserControl> 

BGrid.xaml.cs

public partial class BGrid : UserControl { 
    static public DependencyProperty BProperty { get; private set; } 

    static BGrid() { 
     BProperty = DependencyProperty.Register("B", typeof(B), typeof(BGrid)); 
    } 

    public B B { 
     get { return (B)GetValue(BProperty); } 
     set { SetValue(BProperty, value); } 
    } 

    public BGrid() { 
     InitializeComponent(); 
    } 
} 

CGrid.xaml

<UserControl 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Class="wpfStackOverflow.CGrid" 
    DataContext="{Binding RelativeSource={RelativeSource Self}, Path=C}" 
    > 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto"/> 
      <ColumnDefinition /> 
     </Grid.ColumnDefinitions> 

     <Label Grid.Column="0" Content="Property"/> 
     <TextBox Grid.Column="1" Text="{Binding Property}"/> 
    </Grid> 
</UserControl> 

CGrid.xaml.cs

public partial class CGrid : UserControl { 
    static public DependencyProperty CProperty { get; private set; } 

    static CGrid() { 
     CProperty = DependencyProperty.Register("C", typeof(C), typeof(CGrid)); 
    } 

    public C C { 
     get { return (C)GetValue(CProperty); } 
     set { SetValue(CProperty, value); } 
    } 

    public CGrid() { 
     InitializeComponent(); 
    } 
} 

Window1.xaml

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:wpfStackOverflow" 
    x:Class="wpfStackOverflow.Window1" 
    Width="400" 
    Height="200" 
> 
    <local:AGroupBox x:Name="aGroupBox" /> 
</Window> 

Window1.xaml.cs

public partial class Window1 : Window { 
    public Window1() { 
     InitializeComponent(); 

     aGroupBox.A = new A() 
     { 
      Property = "A's Custom Property Value", 
      B = new B() 
      { 
       Property = "B's Custom Property Value" 
      }, 
      C = new C() 
      { 
       Property = "C's Custom Property Value" 
      } 
     }; 
    } 
} 
+0

Nous allons devoir voir le XAML pour la AGroupBox - en particulier la déclaration contraignante - afin d'aider ici. Je suppose que vos instructions de liaison ne sont pas configurées correctement pour accéder aux données appropriées. En outre, quelle est la lecture du message d'échec de liaison dans la sortie de débogage? –

Répondre

1

Essayez de remplacer ce qui suit dans AGroupBox.xaml

<local:BGrid B="{Binding Path=A.B, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type local:AGroupBox}}}"/> 
<local:CGrid C="{Binding Path=A.C, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type local:AGroupBox}}}"/> 

Il n'a pas été résoudre le datacontext correctement pour ces deux lignes, et n'a donc pas été regardant dans le bon endroit pour B et C.

+0

Merci pour l'aide! J'ai regardé dans la sortie de débogage de la fenêtre de sortie dans Visual Studio et n'a pas d'avertissement de liaison, comment avez-vous identifié le problème? Des pensées sur une solution moins verbeuse? – GEL

+0

Voici un lien vers un bon article sur quelques techniques de débogage pour la reliure: http://beacosta.com/blog/?p=52 Je sais qu'il y a une façon plus propre de le faire (similaire à votre tentative initiale), mais je ne peux pas l'évoquer mentalement en ce moment. –