2009-12-07 4 views
0

У меня есть состав класса DependencyObject, который выглядит следующим образом:WPF Binding Путаница: Композитный 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 { ... } } 
} 

на А, АВ и АС все свойства выполнять типичные ПолучитьЗначение и SetValue операции ссылки статические свойства за обычный.

Теперь классы A, AB и AC имеют соответствующие UserControls AGroupBox, ABGrid, ACGrid. AGroupBox имеет свойство класса корня A, ABGrid имеет корневое свойство класса AB, а ACGrid имеет свойство AC класса root.

И ABGrid, и ACGrid имеют рабочие привязки (например, ABGrid Содержит элемент управления TextBox, свойство Text которого привязано к свойству AB.) Я проверил это, создав простое Окно и имеющее только дочерние элементы содержимого ABGrid be Window и в код за настройкой ABGrid.AB = новый AB(); такой же сценарий для ACGrid.AC = новый AC() ;.

Проблема в том, что я пытаюсь сделать аналогично с AGroupBox. Я пытаюсь добавить AGroupBox в качестве единственного дочернего содержимого Window в XAML и установить свойство AGroupBox.A для нового A() {AB = new AB(), AC = new AC()}; и привязка элементов управления не выполняется. AB и AC имеют значения по умолчанию для своих свойств PropertyN.

Любые идеи о том, что мне не хватает? Есть ли другой маршрут, который я должен взять?

EDIT: Дополнительный комментарий. Если я добавлю свойство строки в A, (String1) и привяжу его к текстовой части GroupBox, тогда привязка к этому свойству работает, но не к AC и AB-свойству A.

EDIT-2: по желанию Дэвида Хэя (весь код находится в пространстве имен 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

Мы будем иметь, чтобы увидеть код XAML для AGroupBox - в частности, обязательная декларация - чтобы помочь здесь. Я предполагаю, что ваши инструкции привязки не настроены правильно для доступа к соответствующим данным. Кроме того, что такое считывание сообщения об ошибке связи в отладочном выходе? –

ответ

1

Попробуйте заменить следующее в 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}}}"/> 

Это не было разрешения DataContext правильно для этих двух линий, и поэтому не смотрел в нужном месте для B и C.

+0

Спасибо за помощь! Я просмотрел вывод debug из окна «Вывод» в Visual Studio и не имел никаких обязательных предупреждений, как вы решили идентифицировать проблему? Любые мысли о менее подробном решении? – GEL

+0

Вот ссылка на хорошую статью о некоторых методах отладки для привязки: http://beacosta.com/blog/?p=52 Я знаю, что есть более чистый способ сделать это (аналогично вашей первоначальной попытке), но я не могу вызвать его мысленно. –

Смежные вопросы