2010-09-30 22 views
0

好的...這裏有兩個人。 (中排序。實際上可能只是一個,那就是我希望反正。)修改或「調整」現有的TreeViewItem控件模板?

首先,更普遍的,是有可能的目標,僅通過XAML,在控制的模板命名的項目?例如,如果控件的模板有一個名爲'PART_Foo'的ContentPresenter,並且我們想通過純樣式將該特定項目上的Horizo​​ntalAlignment設置爲'Stretch',是否可以完成?我知道我們可以在子類的OnApplyTemplate覆蓋中做到這一點,我們通過名稱顯式地搜索控件,然後在代碼中設置屬性,但是我們希望只使用僅限XAML的解決方案,因此我們可以通過樣式嚴格執行此操作而不是子類,除了特定的用例場景之外,它們大多不鼓勵使用。

另外,我們做不是想要手動指定控件的模板,因爲我們希望當前主題確定該模板是什麼,從而確定控件是如何顯示的。我們只想說'在主題選擇的任何模板中,如果有一個名爲'foo'的部分,通過純樣式設置該屬性。如果找不到那個名字的部分,什麼也不要做!

對僅使用XAML方法的期望更多的是因爲第二部分,我們將目標定位爲生成的容器對象,而不是控件本身,意味着它不會是直接的子類,因爲我們會必須用ItemcontainerGenerators等來解決這個問題,這對$$是一個真正的痛苦,特別是當ItemsControl被虛擬化時。

對於具體情況,我們的最終目標是在TreeView的TreeViewItem模板中選出名爲'Bd'的邊框,並將其附加屬性'Grid.ColumnSpan'設置爲'2'而不是默認值'1'。而已!它令我驚訝的是,如果沒有手動替換整個TreeViewItem的模板或使用基於代碼隱藏的解決方案,看起來如此簡單似乎幾乎不可能。

+0

順便說一句,這是我們想避免不得不做的只是改變一個臭味的財產! http://msdn.microsoft.com/en-us/library/ms788727.aspx – MarqueIV 2010-09-30 04:26:57

回答

0

不,這是不可能的,只能使用XAML。你至少必須爲此寫一個附加屬性(你可以在XAML中使用)。只有在運行時沒有任何控件正在創建時纔會有效,因爲它發生在虛擬化列表中。它看起來像這樣:c:TemplateHelper.ReplaceStretchForTemplateItemName="PART_Foo"。在更改後的處理程序中,您可以使用VisualTreeHelper來遍歷該控件的可視子樹,然後查找該名稱並應用所需的任何內容。

修改這樣的模板是有缺陷的,並且被認爲是不好的做法。非常有利的是,有一個主題,或者將來會沒有「Part_Foo」,或者「Part_Foo」與您預期的完全不同。主題和ControlTemplates可能會更改。隨着Microsoft更新其操作系統,新主題將出現(並自動應用於您的應用程序),並且如果您支持自定義主題,則設計者可能會想出不同的主題。

你可能會認爲這是ControlTemplates的一個缺點,它在某種程度上是它的缺點。但是,然後再次嘗試在Windows窗體(或這個星球上的任何其他UI框架)中定製控件... 只是,當習慣了WPF的巨大可靠性時,它很難接受限制,在這種情況下,這是有限的。

+0

我很好的目標控制可能會或可能不會在那裏,因爲唯一的其他選項,完全取代TreeViewItem的控制模板無論如何,都可以控制主題的能力!如果我們將風格放置在本地資源中,它會覆蓋主題,如果我們將它放在可以爲主題的地方,這可能會破壞我們的設計,因爲不保證兒童首先被拉伸。唯一的好處是TreeViewItem的主題可能性很小,因爲唯一的可視化是按鈕和背景突出顯示。其他一切都與位置有關。 – MarqueIV 2010-09-30 19:21:03

+1

我仍然不能相信TreeView上沒有「全行選擇」選項,並且您必須通過所有這些箍來創建它!瘋!!有一件事,雖然......我沒有看到附加屬性,但沒有看到如何使用基於容器的項目控件。我的意思是你必須在容器被其數據源驅動創建容器時設置屬性,而不僅僅是當你在控件本身設置屬性時,所以你就回到了子類的噩夢。 – MarqueIV 2010-09-30 19:21:43

+0

您是否嘗試過在ItemsContainerStyle中設置該屬性?我會假設它應該在創建TreeViewItem時應用。當您啓用虛擬化時,您可能會遇到一些問題。 – bitbonk 2010-10-01 07:51:17