2011-05-13 111 views
1

我想動態添加一個按鈕到網格內的WrapPanel,但WrapPanel引用(_innerPanel屬性)在OnApplyTemplate被調用之前是無效的。強制OnApplyTemplate執行

這裏是XMAL:

<s:MyGrid> 
    <WrapPanel x:Name="PART_InnerPanel"> 

    </WrapPanel> 
</s:MyGrid> 

MyGrid類:

public class MyGrid: Grid 
{ 
    WrapPanel _innerPanel; 

    public WrapPanel Panel 
    { 
     get{return _innerPanel;} 
    } 

    static MyGrid() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(MyGrid), new FrameworkPropertyMetadata(typeof(MyGrid))); 
    } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 
     _innerPanel = Template.FindName("PART_InnerPanel", this) as WrapPanel; 
     if (_innerPanel == null) 
      throw new ResourceReferenceKeyNotFoundException("Invalid template"); 
    } 
} 

裏面的代碼:

MyGrid g = new MyGrid(); 
g.ApplyTemplate(); // <-- doesn't do anything 
g.UpdateLayout(); // <-- doesn't do anything 
if(g.Panel != null) // <-- it's NULL here as OnApplyTemplate hasn't get called 
{ 
    g.Panel.Children.Add(new Button()); 
} 

如何獲得WrapPanel的參考,在XAML正確的定義行後

MyGrid g = new MyGrid(); 

或者任何解決方法或更好的方法來做到這一點?

回答

0

我使用的解決方案是通過在OnApplyTemplate覆蓋中設置_innerPanel(和你一樣)並且當我想使用它時總是檢查它爲空。

我從不向外公開該字段,因爲不能保證模板設計人員將添加該控件。如果你像你這樣做一個檢查有一個保證,但你仍然依賴於WPF引擎加載模板。

只有在控件被構建後才能將控件添加到樹中並找到模板。

所以我認爲你不能有你所要求的。

0

您必須從ItemsControl派生控件才能將子項添加到您的控件中。暴露Panel並不是好的做法,而是在ItemsControl的Items屬性內添加項目,ItemsControl爲您提供了很多方法來自定義外觀。

+0

我這樣做只是爲了顯示我想要以最簡單的方式做什麼。它不需要在這裏是WrapPanel,它可以是網格,畫布,列表,樹或任何其他容器。 – 2011-05-14 16:17:03