簡體   English   中英

WPF綁定混亂:復合DependencyObject

[英]WPF Binding Confusion: Composite DependencyObject

我有一個如下的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具有根A類的根屬性,ABGrid具有根AB類的根屬性,而ACGrid具有根AC類的根屬性。

ABGrid和ACGrid都具有有效的綁定(例如,ABGrid包含一個TextBox控件,其Text屬性雙向綁定到AB的Property1。)我已經通過創建一個簡單的Window並將ABGrid成為Window的唯一Content子對象以及設置背后的代碼來驗證了這一點。 ABGrid.AB =新的AB(); ACGrid.AC = new AC();的情況相同。

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

關於我所缺少的任何見解? 我應該走其他路線嗎?

編輯:附加注釋-如果我將字符串屬性添加到A,(String1)並將其綁定到GroupBox的Text部分,則對該屬性的綁定有效,但對A的AC和AB屬性無效。

EDIT-2:根據David Hay的請求(所有代碼都在命名空間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";
    }
}

抄送

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"
            }
        };
    }
}

嘗試將以下內容替換為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}}}"/>

它沒有為這兩行正確地解析數據上下文,因此沒有為B和C尋找合適的位置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM