2009-04-27 46 views
3

我正在製作自定義控件 - 特別是餅圖。我想要標記看起來像這個例子:WPF - 在自定義控件的內容項中使用數據綁定必須滿足哪些條件?

<c:PieChart> 
    <!-- These dependency properties are never set --> 
    <c:Slice Value="{Binding RedCount}" /> 
    <c:Slice Value="{Binding BlueCount}" /> 
    <c:Slice Value="{Binding GreenCount}" /> 
</c:PieChart> 

PieChartControl派生:

[ContentProperty("Slices")] 
public class PieChart : Control 
{ 
    public PieChart() 
    { 
     Slices = new ObservableCollection<Slice>(); 
    } 

    public ObservableCollection<Slice> Slices { get; private set; } 
} 

以上XAML導致與Slice三個實例來填充Slices財產。

這裏有一個片段從Slice

public class Slice : ContentControl 
{ 
    public static DependencyProperty ValueProperty 
     = DependencyProperty.Register(
      "Value", typeof(double), typeof(Slice), 
      new PropertyMetadata((p,a) => ((Slice)p).OnValueChanged(a))); 

    private void OnValueChanged(DependencyPropertyChangedEventArgs e) 
    { 
     // This code never called! 
    } 
} 

的問題是SliceValue屬性從未設置。如果我將依賴屬性放在PieChart上並複製綁定表達式,那麼該值就會被設置,所以我確信我理解了依賴屬性和綁定的基礎知識。

那麼,我必須做什麼來讓我的依賴項屬性設置子項上的值?由於這些項目都在我自己的集合中,它們是不是在邏輯樹中被任何魔術所認可的綁定工作?

一個簡單的'做這個'的答案會有幫助,但我真的很想知道這裏發生了什麼問題,所以我會接受發佈的最具洞察力和解釋性答案。

編輯我沒有說清楚,但有上包含的屬性RedCount等。在過去的PieChartDataContext一些環境對象,當我有一個綁定的路徑錯字(或者其他一些錯誤)我在運行時在VS輸出窗口中看到了警告。在這種情況下,我什麼都看不到。

回答

3

它看起來像Slice控件沒有掛鉤到視覺樹。它們只是成員變量,而WPF並不知道它是將它們顯示爲PieChart的子元素。幾種可能的方法:

PieChart調用AddLogicalChild添加Slice對象。您將需要處理在運行時添加或從集合中刪除Slice的可能性。這是相當低的水平:MSDN建議:「對於控制作者而言,在這個級別上操作邏輯樹不是推薦的做法,除非沒有可用的基本控件類的內容模型適合您的控制場景。請考慮在級別上進行子類化ContentControlItemsControlHeaderedItemsControl「。

製造PieChart a PanelSlice將成爲它的子女,但請注意Children屬性鍵入較弱,因此人們可以將任何內容添加到PieChart。這本質上不是壞事或好事;這是一個設計考慮(見下面的註釋)。但這可能不是你想要的。

PieChart一個ItemsControl,並覆蓋GetContainerForItemOverrideIsItemItsOwnContainerOverride和可能PrepareContainerForItemOverride創建/尊重Slice控制。 (參看ListBoxListBoxItemComboBoxComboBoxItem等)的這方面的一個很好的特性是用戶可以然後使用ItemsSourceDataTemplate(如ListBox),而不是具有手動創建的子控件。 (但用戶仍可以按您的語法XAML創建固定Slice S,只是因爲他們可以在XAML創建ListBoxItems

你甚至可以考慮一種混合的方法,例如將徑向佈局功能分解爲RadialLayoutPanel,並將餅狀切片生成分解爲使用RadialLayoutPanel作爲其ItemsPanelItemsControl

0

我認爲你看到的問題是綁定嘗試使用錯誤的源。我懷疑像這樣的東西會爲你工作:

<c:PieChart> 
    <!-- These dependency properties are never set --> 
    <c:Slice Value="{Binding RedCount, RelativeSource={AncestorType c:PieChart}}" /> 
    <c:Slice Value="{Binding BlueCount, RelativeSource={AncestorType c:PieChart}}" /> 
    <c:Slice Value="{Binding GreenCount, RelativeSource={AncestorType c:PieChart}}" /> 
</c:PieChart> 

我認爲這很接近,但我可能會離開。我現在無法真正查看它。但這對我來說很好。 (對不起,如果它是完全錯誤:))

+0

再次閱讀問題後,我不認爲這些值首先來自PieChart類......這使得這完全沒有意義。別客氣。 – MojoFilter 2009-04-27 20:49:30