WPF - Plantillas
Una plantilla describe el aspecto general y el aspecto visual de un control. Para cada control, hay una plantilla predeterminada asociada a él que le da al control su apariencia. En las aplicaciones de WPF, puede crear fácilmente sus propias plantillas cuando desee personalizar el comportamiento visual y la apariencia visual de un control.
La conectividad entre la lógica y la plantilla se puede lograr mediante el enlace de datos. La principal diferencia entrestyles y templates se enumeran a continuación:
Los estilos solo pueden cambiar la apariencia de su control con las propiedades predeterminadas de ese control.
Con las plantillas, puede acceder a más partes de un control que en estilos. También puede especificar el comportamiento nuevo y existente de un control.
Hay dos tipos de plantillas que se utilizan con más frecuencia:
- Plantilla de control
- Plantilla de datos
Plantilla de control
La plantilla de control define la apariencia visual de un control. Todos los elementos de la interfaz de usuario tienen algún tipo de apariencia y comportamiento, por ejemplo, Button tiene apariencia y comportamiento. El evento de clic o el evento de desplazamiento del mouse son los comportamientos que se activan en respuesta a un clic y al pasar el mouse, y también hay una apariencia predeterminada del botón que se puede cambiar mediante la plantilla de Control.
Ejemplo
Tomemos un ejemplo sencillo. Crearemos dos botones (uno es con plantilla y el otro es el botón predeterminado) y los inicializaremos con algunas propiedades.
<Window x:Class = "TemplateDemo.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
Title = "MainWindow" Height = "350" Width = "604">
<Window.Resources>
<ControlTemplate x:Key = "ButtonTemplate" TargetType = "Button">
<Grid>
<Ellipse x:Name = "ButtonEllipse" Height = "100" Width = "150" >
<Ellipse.Fill>
<LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4">
<GradientStop Offset = "0" Color = "Red" />
<GradientStop Offset = "1" Color = "Orange" />
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<ContentPresenter Content = "{TemplateBinding Content}"
HorizontalAlignment = "Center" VerticalAlignment = "Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property = "IsMouseOver" Value = "True">
<Setter TargetName = "ButtonEllipse" Property = "Fill" >
<Setter.Value>
<LinearGradientBrush StartPoint = "0,0.2" EndPoint = "0.2,1.4">
<GradientStop Offset = "0" Color = "YellowGreen" />
<GradientStop Offset = "1" Color = "Gold" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property = "IsPressed" Value = "True">
<Setter Property = "RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX = "0.8" ScaleY = "0.8"
CenterX = "0" CenterY = "0" />
</Setter.Value>
</Setter>
<Setter Property = "RenderTransformOrigin" Value = "0.5,0.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<Button Content = "Round Button!"
Template = "{StaticResource ButtonTemplate}"
Width = "150" Margin = "50" />
<Button Content = "Default Button!" Height = "40"
Width = "150" Margin = "5" />
</StackPanel>
</Window>
Cuando compile y ejecute el código anterior, mostrará la siguiente ventana principal.
Cuando mueva el mouse sobre el botón con plantilla personalizada, cambiará su color como se muestra a continuación.
Plantilla de datos
Una plantilla de datos define y especifica la apariencia y estructura de una colección de datos. Proporciona la flexibilidad de formatear y definir la presentación de los datos en cualquier elemento de la interfaz de usuario. Se utiliza principalmente en controles de elementos relacionados con datos, como ComboBox, ListBox, etc.
Ejemplo
Tomemos un ejemplo simple para comprender el concepto de plantilla de datos. Cree un nuevo proyecto de WPF con el nombreWPFDataTemplates.
En el siguiente código XAML, crearemos una plantilla de datos como recurso para contener etiquetas y cuadros de texto. También hay un botón y un cuadro de lista para mostrar los datos.
<Window x:Class = "WPFDataTemplates.MainWindow"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local = "clr-namespace:WPFDataTemplates"
xmlns:loc = "clr-namespace:WPFDataTemplates"
mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525">
<Window.Resources>
<DataTemplate DataType = "{x:Type loc:Person}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height = "Auto" />
<RowDefinition Height = "Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width = "Auto" />
<ColumnDefinition Width = "200" />
</Grid.ColumnDefinitions>
<Label Name = "nameLabel" Margin = "10"/>
<TextBox Name = "nameText" Grid.Column = "1" Margin = "10"
Text = "{Binding Name}"/>
<Label Name = "ageLabel" Margin = "10" Grid.Row = "1"/>
<TextBox Name = "ageText" Grid.Column = "1" Grid.Row = "1" Margin = "10"
Text = "{Binding Age}"/>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height = "Auto" />
<RowDefinition Height = "*" />
</Grid.RowDefinitions>
<ListBox ItemsSource = "{Binding}" />
<StackPanel Grid.Row = "1" >
<Button Content = "_Show..." Click = "Button_Click" Width = "80" HorizontalAlignment = "Left" Margin = "10"/>
</StackPanel>
</Grid>
</Window>
Aquí está implementation in C# en el que se asigna una lista de objetos Person a DataContext, implementación de la clase Person y evento de clic de botón.
using System.Collections.Generic;
using System.Windows;
namespace WPFDataTemplates {
public partial class MainWindow : Window {
Person src = new Person { Name = "Ali", Age = 27 };
List<Person> people = new List<Person>();
public MainWindow() {
InitializeComponent();
people.Add(src);
people.Add(new Person { Name = "Mike", Age = 62 });
people.Add(new Person { Name = "Brian", Age = 12 });
this.DataContext = people;
}
private void Button_Click(object sender, RoutedEventArgs e) {
string message = src.Name + " is " + src.Age;
MessageBox.Show(message);
}
}
public class Person {
private string nameValue;
public string Name {
get { return nameValue; }
set { nameValue = value; }
}
private double ageValue;
public double Age {
get { return ageValue; }
set {
if (value != ageValue) {
ageValue = value;
}
}
}
}
}
Cuando compile y ejecute el código anterior, producirá la siguiente ventana. Contiene una lista y dentro del cuadro de lista, cada elemento del cuadro de lista contiene los datos del objeto de la clase Persona que se muestran en las etiquetas y los cuadros de texto.