2009-12-07 72 views
0

我有一個DependencyObject的階級成分,看起來像如下:WPF綁定的困惑:複合的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 { ... } } 
} 

在A,AB和AC的所有屬性執行典型的GetValue和操作的SetValue引用往常一樣靜態屬性。

現在,類A,AB和AC具有相應的UserControls AGroupBox,ABGrid,ACGrid。 AGroupBox有一個根類屬性,ABGrid有一個根AB類屬性,ACGrid有一個根AC類屬性。

ABGrid和ACGrid都有工作綁定(例如,ABGrid包含Text屬性雙向綁定到AB的Property1的TextBox控件)。我已通過創建一個簡單的窗口並使ABGrid是Window的唯一內容子級來驗證此問題,並且後面的代碼ABGrid.AB = new AB(); ACGrid.AC = new AC();相同的場景。

問題是當我嘗試與AGroupBox類似的時候。我嘗試添加AGroupBox作爲XAML中Window內容的單個子項,並將AGroupBox.A屬性設置爲新的A(){AB = new AB(),AC = new AC()};並且控件的綁定失敗。 AB和AC具有其PropertyN屬性的默認值。

關於我失蹤的任何見解?我應該採取不同的路線嗎?

編輯:其他評論 - 如果我將字符串屬性添加到A,(String1)並將其綁定到GroupBox的文本部分,則對該屬性的綁定起作用,但不會對A的AC和AB屬性起作用。

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正確的地方 - 特別是綁定聲明 - 爲了幫助這裏。我的猜測是你的綁定語句沒有正確設置來訪問適當的數據。另外,在調試輸出中讀取綁定失敗消息是什麼? – 2009-12-07 17:34:57

回答

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

感謝您的協助!我查看了Visual Studio輸出窗口中的調試輸出,並沒有發出任何綁定警告,您是如何確定問題的?對不太詳細的解決方案有任何想法? – GEL 2009-12-07 20:10:13

+0

這裏有一篇關於綁定的一些調試技巧的好文章的鏈接: http://beacosta.com/blog/?p=52 我知道有一個更乾淨的方法來做到這一點(類似於您的初始嘗試),但我現在無法在思想上想起它。 – 2009-12-07 21:03:57