2010-07-29 56 views
4

比方說,我已經創建XAML中定義的以下的ContentTemplate一個用戶控件:如何以編程方式訪問ContentTemplate中定義的元素?

<UserControl.ContentTemplate> 
    <DataTemplate> 
     <Ellipse Name="myEllipse" Stroke="White"/> 
     <ContentPresenter Content="{TemplateBinding Content}"/> 
    </DataTemplate> 
</UserControl.ContentTemplate> 

我將如何訪問我的代碼中的「myEllipse」元素,這樣,例如,我能找到它與「高度myEllipse.Height「?我無法直接通過名稱訪問它。我試圖創建一個參考:

Ellipse ellipse = ContentTemplate.FindName("myEllipse",this) as Ellipse; 

它運行程序時崩潰,說它不能創建我的類的實例。也許我沒有正確使用FindName。如果任何人都可以幫助我,將不勝感激。

感謝,

達拉爾

回答

5

爲了使用FindName上一個DataTemplate,你需要將ContentPresenter參考。見Josh Smith的文章How to use FindName with a ContentControl

你實際上想要做的是使用ControlTemplate而不是DataTemplate。這應該更易於使用,並且會讓您的控件的用戶應用他們自己的內容模板或使用隱式模板。如果你做這樣的事情:

<UserControl.Template> 
    <ControlTemplate TargetType="UserControl"> 
     <Grid> 
      <ContentPresenter/> 
      <Ellipse Name="myEllipse" Stroke="White"/> 
     </Grid> 
    </ControlTemplate> 
</UserControl.Template> 

然後在代碼(也許在OnApplyTemplate重寫),你就可以做到這一點:

var ellipse = Template.FindName("myEllipse", this) as Ellipse; 

你也應該用TemplatePartAttribute這樣的裝飾類:

[TemplatePart(Name="myEllipse", Type = typeof(Ellipse))] 

因此,如果有人重新模板您的控件,他們知道提供一個帶有該名稱的橢圓元素。 (如果該類僅在內部使用,則此類重要性較低)。

最後,如果您只想更改橢圓的顏色,那麼您可能只是想使用數據綁定。你可以在你的控件上創建一個EllipseColor依賴屬性,並設置Stroke="{TemplateBinding EllipseColor}"

+0

感謝您提供非常豐富的答案。我嘗試使用ControlTemplate代替我的DataTemplate,但我的UserControl看起來不一樣,並且某些功能受到了影響,所以我寧願嘗試使用DataTemplate來處理它,現在我已經瞭解了這一點我的控制發展。 在閱讀Josh Smith的文章後,我試着在構造函數中爲我的控件添加以下行: ContentPresenter contentPresenter = VisualTreeHelper.GetChild(this,0)as ContentPresenter; 不幸的是,它在該行失敗。我得到一個XAML解析異常。有任何想法嗎? – Dalal 2010-07-29 22:20:11

+1

@Dalal:構造函數中尚未填充可視化樹,所以在GetChild調用中出現超出範圍的異常。這被封裝在一個XAML解析異常中,因爲它沒有實例化你的對象。您將需要將代碼移到Load事件處理程序或OnApplyTemplate覆蓋。另外,UserControl的默認控件模板在Border中有一個ContentPresenter,因此'VisualTreeHelper.GetChild(this,0)'將返回一個Border。你需要做一些像'VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(this,0),0)'。 – Quartermeister 2010-07-30 02:40:40

+0

在我OnApplyTemplate重寫我能順利拿到ContentPresenter使用行'VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(此,0),0)作爲ContentPresenter;'現在我不得不引用名爲我的對象之一「 headerLabel',所以我把'headerLabel = ContentTemplate.FindName(「headerLabel」,contentPresenter)作爲Label;'我得到一個InvalidOperationException:這個操作只對應用這個模板的元素有效。那麼,教程說在ContentPresenter中傳遞。我做到了。我也試着把這段代碼放在MouseDown事件中無濟於事。 – Dalal 2010-07-30 18:08:58

相關問題