Câu trả lời:
Thông thường, một điều khiển được hiển thị cho mục đích riêng của nó và không phản ánh dữ liệu cơ bản. Ví dụ: Button
sẽ không bị ràng buộc với một đối tượng kinh doanh - nó hoàn toàn ở đó để có thể nhấp vào nó. Một ContentControl
hoặc ListBox
, tuy nhiên, thường xuất hiện để họ có thể trình bày dữ liệu cho người dùng.
DataTemplate
Do đó, A được sử dụng để cung cấp cấu trúc trực quan cho dữ liệu cơ bản, trong khi a ControlTemplate
không liên quan gì đến dữ liệu cơ bản và chỉ đơn giản là cung cấp bố cục trực quan cho chính điều khiển.
A ControlTemplate
nói chung sẽ chỉ chứa các TemplateBinding
biểu thức, liên kết lại với các thuộc tính trên chính điều khiển, trong khi a DataTemplate
sẽ chứa các biểu thức Binding tiêu chuẩn, liên kết với các thuộc tính của nó DataContext
(đối tượng doanh nghiệp / miền hoặc mô hình xem).
Về cơ bản, ControlTemplate
mô tả cách hiển thị Điều khiển trong khi DataTemplate
mô tả cách hiển thị Dữ liệu.
Ví dụ:
A Label
là một điều khiển và sẽ bao gồm một ControlTemplate
điều khiển cho biết Label
nên được hiển thị bằng cách sử dụng Border
xung quanh một số Nội dung (một DataTemplate
hoặc một Điều khiển khác).
Một Customer
lớp là Dữ liệu và sẽ được hiển thị bằng cách sử dụng một DataTemplate
loại có thể nói để hiển thị Customer
loại dưới dạng StackPanel
chứa hai TextBlocks
cái hiển thị Tên và cái còn lại hiển thị số điện thoại. Có thể hữu ích khi lưu ý rằng tất cả các lớp được hiển thị bằng cách sử dụng DataTemplates
, bạn thường sẽ chỉ sử dụng mẫu mặc định là TextBlock
thuộc Text
tính được đặt thành kết quả của ToString
phương thức Object .
Troels Larsen có một lời giải thích tốt trên diễn đàn MSDN
<Window x:Class="WpfApplication7.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <DataTemplate x:Key="ButtonContentTemplate"> <StackPanel Orientation="Horizontal"> <Grid Height="8" Width="8"> <Path HorizontalAlignment="Stretch" Margin="0,0,1.8,1.8" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" Data="M0.5,5.7 L0.5,0.5 L5.7,0.5"/> <Path HorizontalAlignment="Stretch" Margin="2,3,0,0" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" Data="M3.2,7.5 L7.5,7.5 L7.5,3.5"/> <Path HorizontalAlignment="Stretch" Margin="1.2,1.4,0.7,0.7" VerticalAlignment="Stretch" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF000000" Data="M2.5,2.5 L7.5,7.5"/> <Path HorizontalAlignment="Stretch" Margin="1.7,2.0,1,1" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" Data="M3,7.5 L7.5,7.5 L7.5,3.5"/> <Path HorizontalAlignment="Stretch" Margin="1,1,1,1" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" Data="M1.5,6.5 L1.5,1 L6.5,1.5"/> </Grid> <ContentPresenter Content="{Binding}"/> </StackPanel> </DataTemplate> <ControlTemplate TargetType="Button" x:Key="ButtonControlTemplate"> <Grid> <Ellipse Fill="{TemplateBinding Background}"/> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid> </ControlTemplate> </Window.Resources> <StackPanel> <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="1"/> <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="2"/> <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="3"/> </StackPanel> </Window>
(Các mẫu bị đánh cắp một cách trắng trợn từ http://msdn.microsoft.com/en-us/l Library / system.windows.controls.controltemplate.aspx và http://msdn.microsoft.com/en-us/l Library / system.windows .controls.contentcontrol.contenttemplate% 28VS.95% 29.aspx tương ứng)
Dù sao, ControlTemplate quyết định giao diện của Nút, trong khi ContentTemplate quyết định nội dung của nút trông như thế nào. Vì vậy, bạn có thể liên kết nội dung với một trong các lớp dữ liệu của mình và để nó hiện diện theo cách bạn muốn.
ControlTemplate
: Thể hiện phong cách điều khiển.
DataTemplate
: Thể hiện kiểu dữ liệu (Bạn muốn hiển thị dữ liệu của mình như thế nào).
Tất cả các điều khiển đang sử dụng mẫu điều khiển mặc định mà bạn có thể ghi đè thông qua thuộc tính mẫu.
Ví dụ
Button
mẫu là một mẫu điều khiển.
Button
mẫu nội dung là một mẫu dữ liệu
<Button VerticalAlignment="Top" >
<Button.Template>
<ControlTemplate >
<Grid>
<Rectangle Fill="Blue" RadiusX="20" RadiusY="20"/>
<Ellipse Fill="Red" />
<ContentPresenter Content="{Binding}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="50">
<TextBlock Text="Name" Margin="5"/>
<TextBox Text="{Binding UserName, Mode=TwoWay}" Margin="5" Width="100"/>
<Button Content="Show Name" Click="OnClickShowName" />
</StackPanel>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
public String UserName
{
get { return userName; }
set
{
userName = value;
this.NotifyPropertyChanged("UserName");
}
}
ControlTemplate
Xác định giao diện trực quan, thay DataTemplate
thế giao diện trực quan của mục dữ liệu.
Ví dụ: Tôi muốn hiển thị một nút từ dạng hình chữ nhật đến hình tròn => Mẫu điều khiển.
Và nếu bạn có các đối tượng phức tạp để điều khiển, nó chỉ gọi và hiển thị ToString()
, với DataTemplate
bạn có thể nhận được nhiều thành viên khác nhau và hiển thị và thay đổi giá trị của đối tượng dữ liệu.
Tất cả các câu trả lời trên là tuyệt vời nhưng có một sự khác biệt chính đã bị bỏ qua. Điều đó giúp đưa ra quyết định tốt hơn về thời điểm sử dụng những gì. Đây là ItemTemplate
tài sản:
DataTemplate được sử dụng cho các thành phần cung cấp thuộc tính ItemTemplate để bạn thay thế nội dung của các mục của nó bằng cách DataTemplate
bạn xác định trước đó theo dữ liệu bị ràng buộc thông qua bộ chọn mà bạn cung cấp.
Nhưng nếu kiểm soát của bạn không cung cấp sự sang trọng này cho bạn thì bạn vẫn có thể sử dụng một ContentView
điều có thể hiển thị nội dung của nó từ được xác định trước ControlTemplate
. Thật thú vị, bạn có thể thay đổi thuộc ControlTemplate
tính của bạn ContentView
trong thời gian chạy. Một điều nữa cần lưu ý là không giống như các điều khiển với thuộc ItemTemplate
tính, bạn không thể có điều khiển TemplateSelector
này (ContentView). Tuy nhiên, bạn vẫn có thể tạo các kích hoạt để thay đổi ControlTemplate
thời gian chạy.