星期二, 1月 22, 2008

[WPF] ItemsPanel, ItemsTemplate, DataTemplate, ControlTemplate? How to find ItemsPanel from code?

開始初學WPF對於Template其實是很容易一知半解 尤其是一大堆Template的名詞

與許多功能重複的關係 造成搞不清楚狀況

今天我跟同事們又解釋了一次 覺得其實我之前也花了許多時間搞懂 不如就寫下來

順便剛又找到一個問題的workaround解法 也寫下來記錄一下 .....

WPF主要是希望用XAML與Code 的方式 把User Interface與Logics分開

所以可以想到我們要寫一個Control的話......

所有的behavior, property是寫在Code裡

ControlTemplate (also can be defined in Style) 就是幫你把整個Custom Control的程式展開成Visual Tree,就是一大堆小元件,主要是Control 的Presentation....

ItemsTemplate 對於ItemsControl而言 就是將他的Items如何展開成Visual Tree....所以可想而知...ItemsTemplate是一種DataTemplates

DataTemplate 就是描述如何將Data (.net class)展開成Visual Tree (所以也就是我們assign source可以輕鬆地給.net data class,data template會為我們展開)

ItemsPanel就是對於一個ItemsControl而言 就是要去描述要如何layout所有的items,例如可以用StackPanel or WrapPanel.....


哈哈 這樣有比較清楚了嗎?..... 還有一個叫ContentTemplate

ItemsTemplate 之於ItemsControl 就等同於 ContentTemplate 之於 ContentControl
也就是描述如何將Content展開....


ok~~ 接下來是另一個問題 是我個人的經驗.....

何時要用Data Template,何時要用Custom Control,何時要用User Control

彈性而言 DataTemplate >> CustomControl >> UserControl

但是大家也知道 寫UI就是最容易東改西改 而且Control常混雜的很嚴重 也有可能很複雜

有時候很特別的一個UI 並不會需要有reuse的功能 我們可以直接用UserControl解決

但是如果是十分Common的Control 我們可以用CustomControl解決

DataTemplate則是如果能用現有的Control Composite成一個的話 就不需要花時間寫Control

大概是這樣 :D


最後一個問題 當ItemsPanel展開之後 我們沒辦法用Template.FindName找個ItemsPanel裡的Panel怎麼嗎?

我從google找到一個討論串 得enumerate Visual Tree解決 請享用

from http://www.msdner.net/dev-archive/210/153-119-2109609.shtm

private T FindItemsPanel(Visual visual)

{

for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)

{

Visual child = VisualTreeHelper.GetChild(visual, i) as Visual;

if (child != null)

{

if (child is T && VisualTreeHelper.GetParent(child) is ItemsPresenter)

{

object temp = child;

return (T)temp;

}

T panel = FindItemsPanel(child);

if (panel != null)

{

object temp = panel;

return (T)temp; // return the panel up the call stack

}

}

}

return default(T);

}

沒有留言: