DataTemplate and ControlTemplate
The control template is also frequently seen in wp/silverlight/wpf. It is often obfuscated with DataTemplate and ControlTemplate. This article will talk about the relationship between two clothes DataTemplate and ControlTemplate.
Make sure that there are two parts of the Control. One is its content. The content is not a font, but is composed of a control internally. Using DataTemplate is to change the internal control.
The second is its appearance. To change its appearance, use ControlTemplate.
1. DataTemplate in ContentControl (used to display the template of the Content inside the control)
Before getting started, let's take a look at the definition of ContentControl. Both wp and wpf have the following two attributes:
Public object Content {get; set ;}
Public DataTemplate ContentTemplate {get; set ;}
The feature is that only one content can be accommodated, and the content type is the object type. The Button control is a class that we are familiar with and belongs to ContentControl. Let's take a look at using TextBlock as its content, the Button will work very well. For example:
This is normal, because the content is object, so I will use another brush as its content. Result:
The content is displayed as the converted string of the brush. If you look back at the DataTemplate, you will find that its summary is:
Obtain or set a data template used to display the content of System. Windows. Controls. ContentControl. The data template of the content is what the content looks like.
Next I will show the content of the button-the paint brush on a circle.
The button content control is used to display the content of the button in a circle. Of course, by extension, I can use any Content control, set its Content first (the Content can be any complex Content), and then use DataTemplate to express the Content data. Next we will use a UserControl control to implement a Student's information: define a Student class, initialize a stu, set it as the UC Content, and then list the data in the Content.
The preceding two examples show that the DataTemplate in ContentControl is used to represent the data in the Content. That is to say, the Content is the source bound to the DataTemplate. The specific manifestation is determined by the DataTemplate.
2. ControlTemplate of Control (a template used to display the Control appearance)
In Control, there is a Template attribute. Its summary and returned results are as follows:
// Summary:
// Obtain or set the control template.
// Return result:
// Template used to define the appearance of System. Windows. Controls. Control.
Public ControlTemplate Template {get; set ;}
Unlike DataTemplate, the control defines the appearance template. Let's take the Button as an example. The result returned above indicates the appearance template. If I want a Button with a rounded corner, it should belong to the appearance category. Soon I thought of using Border. Let's get started. Let me get a button to write the content and add the background color to him:
Then, the Template attribute is added, and the background color and content are missing.
In this way, we can see that the Content is no longer abc. To show abc, can I add a TextBlock control in Border and write a few letters on the TextBlock? I can see it, but if it is not abc, still, abc cannot be displayed. It means that the content displayed now depends on TextBlock. If there is a kind of binding, I can make TextBlock display consistent with abc. There is a TemplateBinding. The Target must be used in the ControlTemplate label for use. The effect is as follows:
Although the results are achieved, a serious problem is that the Content of our Button is of the object type, and Text is of the string type. If the button is in a bad mood at any time and the Content attribute is changed to Image, do I have to get angry with the Button? To avoid being angry, do you have any containers that use all types of content? The answer is yes. Use ContentPresenter. Now, no matter whether you are an image or a text, I don't need a bird or you have a ContentPresenter. Show his appearance below
ContentPresenter is very standard. It will automatically match the Content and ContentTemplate of Target for you. If the Button. the Content-related attributes (such as FontSize, Foreground, FontFamily, etc.) have changed. You do not need to change the ContentPresenter. This will help us deal with it well, but if it is a property related to the Button itself, (such as the background color), must be explicitly adjusted.
3. Contact DataTemplate and ControlTemplate
When ContentPresenter is used in the above example, you will find that it also has a ContentTemplate. Will it be guessed that it is of the DataTemplate type and is "long" on the Template tree ". We can assume that the DataTemplate corresponding to ContentTemplate is a subtree of the ControlTemplate tree corresponding to Template. To prove this fact, we will also describe it with a Button.
Now I use text, images, and brushes as the content of the button in the button respectively, and then add a container to display the child tree of the Template. below is the xaml code:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Button Grid.Row="0" Grid.Column="0" Content="Click to Dump" HorizontalAlignment="Center" VerticalAlignment="Center" Click="OnButtonClick" /> <Button Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Click="OnButtonClick"> <Image Source="Images/vs.png" Stretch="None" /> </Button> <Button Grid.Row="1" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center" Click="OnButtonClick"> <Button.Content> <RadialGradientBrush> <GradientStop Offset="0" Color="Blue" /> <GradientStop Offset="1" Color="AliceBlue" /> </RadialGradientBrush> </Button.Content> <Button.ContentTemplate> <DataTemplate> <Ellipse Width="100" Height="100" Fill="{Binding}" /> </DataTemplate> </Button.ContentTemplate> </Button> <ScrollViewer Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" HorizontalScrollBarVisibility="Auto"> <StackPanel Name="stackPanel" /> </ScrollViewer> </Grid>
I can view the child trees under the Template in the Button Based on the visual tree search (the methods provided by the VisualTreeHelper class are combined with recursive algorithms. The following code is the background code:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } void OnButtonClick(object sender, RoutedEventArgs args) { Button btn = sender as Button; stackPanel.Children.Clear(); DumpVisualTree(btn, 0); } void DumpVisualTree(DependencyObject parent, int indent) { TextBlock txtblk = new TextBlock(); txtblk.Text = String.Format("{0}{1}", new string(' ', 4 * indent), parent.GetType().Name); stackPanel.Children.Add(txtblk); int numChildren = VisualTreeHelper.GetChildrenCount(parent); for (int childIndex = 0; childIndex < numChildren; childIndex++) { DependencyObject child = VisualTreeHelper.GetChild(parent, childIndex); DumpVisualTree(child, indent + 1); } } }
Click each button to see how the Template of each button is constructed. The visual tree contains ContentPresenter. This does not mean that the DataTemplate is replaced by ContentPresenter, it indicates that DataTemplate generates a tree below ContentPresenter (the tree below ContentPresenter in wp and silverlight may be different from that in wpf ). It is also verified that DataTemplate is part of the ControlTemplate subtree.
Iv. Summary
This article mainly introduces DataTemplate and ControlTemplate, introduces ContentPresenter, and uses the visual tree help class VisualTreeHelper to view the template content contained in the control, and then verifies the relationship between DataTemplate and ControlTemplate. If you think there is something wrong with this article, please correct me! Thank you for reading!