Después de la introducción a la plantilla EditTemplate del control DataForm realizada en la primera parte, en esta segunda entrega trataremos algunos aspectos adicionales de dicha plantilla, así como la inserción de nuevos datos utilizando la plantilla NewItemTemplate, proporcionada también por este control. Al igual que en la anterior entrega, el código fuente de los ejemplos está disponible en este enlace.
Deshabilitar el modo de edición automática
Cada vez que ejecutamos el formulario habremos comprobado que podemos editar directamente los campos de la entidad en la que nos posicionamos al navegar por la colección de entidades. Ello es debido a que la propiedad AutoEdit del DataForm tiene el valor true por defecto. Si queremos que sea el usuario quien decida cuándo quiere activar el modo de edición tendremos que asignar el valor false a dicha propiedad.
<toolkit:DataForm x:Name="frmInvoices"
ItemsSource="{Binding ElementName=ddsInvoices, Path=Data}"
Margin="5"
Header="Edición de facturas"
AutoEdit="False">
De esta manera, el DataForm ofrecerá inicialmente los campos en modo de lectura, incorporando un nuevo botón en la barra de herramientas con la imagen de un lapicero. Al hacer clic en dicho botón, el estado de los controles pasará de sólo lectura a edición. Para grabar los cambios realizados en los campos tan sólo es necesario hacer clic en cualquiera de los botones de navegación para movernos a otra entidad, o bien hacer clic en el botón Cancel para deshacer los cambios y devolver los campos a sus valores originales.
La propiedad AutoEdit y la plantilla ReadOnlyTemplate
Si pretendemos utilizar simultáneamente en el DataForm una plantilla EditTemplate y otra ReadOnlyTemplate, hemos de tener en cuenta que mientras que la propiedad AutoEdit tenga el valor true, el DataForm hará caso omiso de la plantilla ReadOnlyTemplate, utilizando solamente la plantilla de edición. Para solucionar este comportamiento bastará con asignar false a la propiedad AutoEdit como vemos a continuación.
<toolkit:DataForm x:Name="frmInvoices"
ItemsSource="{Binding ElementName=ddsInvoices, Path=Data}"
Margin="5"
Header="Edición de facturas"
AutoEdit="False">
<toolkit:DataForm.ReadOnlyTemplate>
<DataTemplate>
<StackPanel>
<toolkit:DataField Label="Código factura:" Description="Número identificador de la factura">
<TextBlock Text="{Binding Path=InvoiceId, Mode=OneWay}" />
</toolkit:DataField>
<toolkit:DataField Label="Código cliente:" Description="Identificador del cliente">
<TextBlock Text="{Binding Path=CustomerId, Mode=OneWay}" />
</toolkit:DataField>
<toolkit:DataField Label="Fecha:">
<TextBlock Text="{Binding Path=InvoiceDate, Mode=OneWay}" />
</toolkit:DataField>
<toolkit:DataField Label="Dirección:">
<TextBlock Text="{Binding Path=BillingAddress, Mode=OneWay}" />
</toolkit:DataField>
<toolkit:DataField Label="Ciudad:">
<TextBlock Text="{Binding Path=BillingCity, Mode=OneWay}" />
</toolkit:DataField>
<toolkit:DataField Label="País:">
<TextBlock Text="{Binding Path=BillingCountry, Mode=OneWay}" />
</toolkit:DataField>
<toolkit:DataField Label="Importe:">
<TextBlock Text="{Binding Path=Total, Mode=OneWay}" />
</toolkit:DataField>
<toolkit:DataField Label="Primera factura?:">
<TextBlock Text="{Binding Path=FirstInvoice, Mode=OneWay}" />
</toolkit:DataField>
</StackPanel>
</DataTemplate>
</toolkit:DataForm.ReadOnlyTemplate>
<toolkit:DataForm.EditTemplate>
<!--....-->
</toolkit:DataForm.EditTemplate>
</toolkit:DataForm>

Confirmando manualmente los cambios realizados a la entidad
Después de editar uno o varios campos del formulario, para que dichos cambios queden guardados en la colección de entidades asociada al DataForm, nos desplazaremos a otra entidad de la colección utilizando los botones de navegación de la barra de herramientas.
Pero en algunos casos puede resultar interesante obligar al usuario a aceptar de forma explícita tales modificaciones. Esto lo podemos conseguir asignando el valor false a la propiedad AutoCommit del control DataForm, la cual contiene true por defecto.
<toolkit:DataForm x:Name="frmInvoices"
ItemsSource="{Binding ElementName=ddsInvoices, Path=Data}"
Margin="5"
Header="Edición de facturas"
AutoEdit="False"
AutoCommit="False">
Una vez hecha esta asignación, cada vez que editemos una entidad del DataForm se mostrará el botón OK, que utilizaremos para aceptar los cambios que hayamos efectuado en los campos del formulario.
El botón OK estará inicialmente deshabilitado y no se habilitará hasta que no hagamos cambios en alguno de los campos del formulario. A partir del momento en el que este botón esté disponible, los botones de la barra de herramientas se deshabilitarán, con lo que el usuario estará obligado a aceptar o cancelar haciendo clic, respectivamente, en OK o Cancel.
Una de las ventajas de confirmar la edición de campos mediante el botón OK radica en que una vez pulsado dicho botón seguiremos posicionados en la misma entidad que estábamos editando. Recordemos que cuando sólo disponemos del botón Cancel tenemos que movernos a otra entidad de la colección para hacer efectivos los cambios.
Como apunte estético adicional conviene saber que las propiedades CommitButtonContent y CancelButtonContent permiten asignar a estos botones un título distinto del que se ofrece por defecto.
<toolkit:DataForm x:Name="frmInvoices"
ItemsSource="{Binding ElementName=ddsInvoices, Path=Data}"
Margin="5"
Header="Edición de facturas"
AutoEdit="False"
AutoCommit="False"
CommitButtonContent="Aceptar cambios"
CancelButtonContent="Salir de edición">
Borrar una entidad de la colección
Podemos utilizar el botón Borrar de la barra de herramientas para eliminar la entidad actual sobre la que está posicionado el DataForm, aunque debemos tener precaución, ya que el borrado se realiza sin pedir confirmación al usuario.
Si queremos prevenir borrados accidentales crearemos un manipulador para el evento DeletingItem, que se producirá durante la solicitud de borrado de un elemento de la colección del formulario, lo cual nos permite anular la operación de borrado asignando el valor true a la propiedad Cancel del tipo CancelEventArgs que este manipulador recibe como parámetro.
<toolkit:DataForm x:Name="frmInvoices"
<--....-->
DeletingItem="frmInvoices_DeletingItem">
private void frmInvoices_DeletingItem(object sender, System.ComponentModel.CancelEventArgs e)
{
if (MessageBox.Show("¿Borrar la factura?", "Atención", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
{
e.Cancel = true;
}
}
NewItemTemplate. Añadiendo nuevos elementos al DataForm
Gracias a la plantilla NewItemTemplate podemos crear una interfaz de usuario específica para los casos en que tengamos que agregar nuevos elementos a la colección de entidades del formulario haciendo clic en el botón Añadir.
El siguiente bloque de código XAML muestra el modo de declaración de esta plantilla.
<toolkit:DataForm ....>
<!--....-->
<toolkit:DataForm.NewItemTemplate>
<DataTemplate>
<StackPanel>
<!--....-->
</StackPanel>
</DataTemplate>
</toolkit:DataForm.NewItemTemplate>
</toolkit:DataForm>
La carencia de esta plantilla no significa que en el formulario no podamos añadir nuevas entidades, ya que en tal situación, el DataForm automáticamente hace uso de la plantilla EditTemplate, utilizándola como plantilla de inserción.
No obstante, la inserción es una operación de edición con ciertas particularidades, que no siempre van a poder ser sustituidas directamente mediante la plantilla EditTemplate.
Por ejemplo, supongamos que en nuestra aplicación, a la hora de crear una nueva factura, los campos del DataForm deben cumplir con una serie de pautas y restricciones, las cuales describiremos en los siguientes apartados, aportando una solución para cada una de ellas.
InvoiceId
La edición de este campo estará restringida en la creación de una factura, ya que como hemos comentado anteriormente, estamos ante un valor que genera automáticamente el motor de datos, por lo que resulta innecesaria su introducción manual por parte del usuario.
Por tal motivo, no incluiremos en la plantilla NewItemTemplate un control para editar este campo.
InvoiceDate
Este campo tampoco podrá ser editado por el usuario, ya que tomará su valor de la fecha del sistema. Sin embargo, a diferencia del anterior, su valor sí tendrá que ser visualizado.
La forma de resolver este problema consistirá, por una parte, en asignar el valor false a la propiedad IsEnabled del DataField que utilizaremos en la definición del campo. Por otro lado, en el code-behind de la página, crearemos un manipulador para el evento ContentLoaded; donde comprobaremos si la operación de edición corresponde a la creación de una nueva entidad (enumeración DataFormMode), y en caso afirmativo, obtendremos la entidad actualmente en curso, asignando la fecha del sistema a su propiedad InvoiceDate.
<toolkit:DataField Label="Fecha:" IsEnabled="False">
<sdk:DatePicker x:Name="dtInvoiceDate"
SelectedDate="{Binding Path=InvoiceDate, Mode=TwoWay}"
Width="110" HorizontalAlignment="Left" />
</toolkit:DataField>
private void frmInvoices_ContentLoaded(object sender, DataFormContentLoadEventArgs e)
{
if (this.frmInvoices.Mode == DataFormMode.AddNew)
{
Invoice oInvoice = (Invoice)this.frmInvoices.CurrentItem;
oInvoice.InvoiceDate = DateTime.Today;
//....
}
}
FirstInvoice
Otro campo que al igual que los dos anteriores no podrá ser modificado, debiendo tomar el valor true, o lo que es igual, mostrar un CheckBox con la casilla marcada.
<toolkit:DataField Label="Primera factura?:" IsEnabled="False">
<CheckBox IsChecked="{Binding Path=FirstInvoice, Mode=TwoWay}" />
</toolkit:DataField>
private void frmInvoices_ContentLoaded(object sender, DataFormContentLoadEventArgs e)
{
if (this.frmInvoices.Mode == DataFormMode.AddNew)
{
Invoice oInvoice = (Invoice)this.frmInvoices.CurrentItem;
//....
oInvoice.FirstInvoice = true;
}
}
BillingAddress
A diferencia de los campos anteriores, la dirección de la factura sí podrá ser editada por el usuario. Sin embargo, este campo tendrá que tomar como valor inicial la cadena "C/", y adicionalmente, al recibir el foco, tendrá que posicionarse al final del texto del control; esto último lo lograremos codificando el evento GotFocus del control de edición.
<toolkit:DataField Label="Dirección:">
<TextBox x:Name="txtBillingAddress" Text="{Binding Path=BillingAddress, Mode=TwoWay}"
Width="150"
GotFocus="txtBillingAddress_GotFocus" />
</toolkit:DataField>
private void txtBillingAddress_GotFocus(object sender, RoutedEventArgs e)
{
((TextBox)sender).Select(((TextBox)sender).Text.Length, 0);
}
CustomerId
El DataForm asigna de manera predeterminada el valor cero a los campos numéricos cuando se trata de nuevas entidades. En el campo CustomerId este comportamiento puede resultar especialmente incómodo, ya que en la práctica totalidad de las ocasiones, el usuario debe borrar el cero y teclear un código válido de cliente. Por tal causa, en el evento GotFocus de este control de edición añadiremos el código necesario para que automáticamente sea borrado su contenido si sólo hay un cero.
<toolkit:DataField Label="Código cliente:">
<TextBox x:Name="txtCustomerId" Text="{Binding Path=CustomerId, Mode=TwoWay}"
Width="40" HorizontalAlignment="Left"
GotFocus="txtCustomerId_GotFocus" />
</toolkit:DataField>
private void txtCustomerId_GotFocus(object sender, RoutedEventArgs e)
{
if (this.frmInvoices.Mode == DataFormMode.AddNew)
{
TextBox txtCustomerId = (TextBox)this.frmInvoices.FindNameInContent("txtCustomerId");
if (txtCustomerId.Text == "0")
{
txtCustomerId.Text = string.Empty;
}
}
}
Tras escribir todo este código declarativo y de comportamiento para la plantilla de inserción, ejecutaremos la aplicación, que tendrá el aspecto de la siguiente figura durante la creación de una nueva entidad.
La creación de nuevos valores utilizando la plantilla NewItemTemplate pone punto final a este artículo, en el que nos hemos aproximado a las operaciones de edición que desde el control DataForm de Silverlight pueden realizarse a través de las plantillas que este control proporciona. Confiamos en que os resulte de utilidad.
Un saludo.
Continuando con la tónica iniciada en el artículo sobre la plantilla ReadOnlyTemplate del control DataForm, en esta ocasión abordaremos el desarrollo de un formulario centrándonos en los aspectos relativos a la edición de datos, utilizando las plantillas que a tal efecto este control proporciona.
En esta primera entrega crearemos el proyecto de ejemplo sobre el que trabajaremos, realizando una introducción al uso de la plantilla EditTemplate, donde explicaremos el comportamiento predeterminado que muestra durante la edición de los datos. En la segunda parte abordaremos la posibilidad de otorgar al usuario un mayor control sobre la operación de edición, así como el borrado de datos. También nos ocuparemos de la inserción de nuevos valores empleando la plantilla NewItemTemplate.
La fuente de datos
En el presente artículo volveremos a usar la base de datos MusicaGest, cuya tabla Invoice está basada en la tabla del mismo nombre de la base de datos Chinook, disponible en CodePlex. Podemos ver el script de creación en el artículo sobre la plantilla ReadOnlyTemplate anteriormente mencionado.
El proyecto de ejemplo
Antes de empezar a trabajar en el diseño de la plantilla crearemos en Visual Studio 2010 el proyecto de ejemplo (de tipo Silverlight Application con WCF RIA Services habilitado) que nos acompañará a lo largo del artículo, al que daremos el nombre de PlantillasEdicion, y cuyo código fuente podemos encontrar aquí.
Obtendremos como resultado una solución compuesta por dos proyectos: uno de ellos será un proyecto Web que representa a la parte servidora de la aplicación, y el otro un proyecto Silverlight que representa a la parte cliente.
Como elementos de partida de la aplicación, en el proyecto Web crearemos un modelo de datos conectado a la base de datos MusicaGest, y un servicio de dominio para manejar la entidad Invoice proporcionada por el modelo de datos.

public class MusicaGestDomainService : LinqToEntitiesDomainService<MusicaGestEntities>
{
public IQueryable<Invoice> GetInvoices()
{
return this.ObjectContext.Invoices;
}
//....
Comportamiento predeterminado en edición
A continuación abriremos la página MainPage.xaml, añadiendo un DomainDataSource y un DataForm, en los que estableceremos la configuración mínima que permita su funcionamiento.
<UserControl x:Class="PlantillaEdicion.MainPage"
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
xmlns:domainctx="clr-namespace:PlantillaEdicion.Web" xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
<--....-->
<riaControls:DomainDataSource x:Name="ddsInvoices" QueryName="GetInvoices">
<riaControls:DomainDataSource.DomainContext>
<domainctx:MusicaGestDomainContext />
</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
<!--....-->
<toolkit:DataForm x:Name="frmInvoices" ItemsSource="{Binding ElementName=ddsInvoices, Path=Data}" Margin="5" >
</toolkit:DataForm>
<!--....-->
El DataForm generará un control de edición (campo) por cada propiedad de la entidad a la que se encuentra enlazada a través del DomainDataSource. Para los valores textuales y numéricos se utilizarán controles TextBox, para las fechas DatePicker, y para los lógicos CheckBox.
Esta sencillez en la creación del formulario de datos arroja algunos inconvenientes, entre los que destacaríamos el hecho de que el nombre de los campos de la tabla se usa para ordenar los campos del DataForm, aunque rara vez el orden de los campos resulta adecuado de esta manera. El nombre del campo también se emplea como título situado al lado de cada control de edición, lo que puede resultar poco descriptivo en ocasiones. Respecto a las dimensiones de los campos, encontramos que todos mantienen la misma anchura, siendo esto algo innecesario en campos como CustomerId, InvoiceDate o Total, por poner un ejemplo.
La plantilla EditTemplate
Si bien podríamos solucionar parte de los problemas que acabamos de plantear aplicando ciertos atributos del espacio de nombres DataAnnotations a los metadatos de la entidad Invoice, tal y como se explica aquí, en esta ocasión vamos a recurrir a la plantilla EditTemplate, que utilizaremos para aquellas operaciones de modificación de los valores existentes en la colección de entidades enlazadas al formulario de datos. Mediante esta plantilla podremos conseguir una interfaz de usuario mucho más flexible y personalizable que la generada por el DataForm automáticamente.
Volviendo al editor de código de la página MainPage.xaml, dentro de la declaración del DataForm situaremos la plantilla utilizando las etiquetas EditTemplate y DataTemplate.
<toolkit:DataForm x:Name="frmInvoices"
ItemsSource="{Binding ElementName=ddsInvoices, Path=Data}"
Margin="5" >
<toolkit:DataForm.EditTemplate>
<DataTemplate>
<StackPanel>
<!--....-->
</StackPanel>
</DataTemplate>
</toolkit:DataForm.EditTemplate>
</toolkit:DataForm>
Como acabamos de comprobar en el anterior bloque de código, también incluiremos un elemento contenedor dentro de DataTemplate (un panel StackPanel), ya que de no hacerlo así, se produciría un error que indicaría que la propiedad VisualTree está asignada más de una vez.
A partir de aquí, para cada campo que queramos añadir al DataForm agregaremos una etiqueta DataField (igual que en la plantilla ReadOnlyTemplate), en cuyo interior situaremos el control con el que editaremos el valor del campo, o bien, un control de sólo lectura en caso de que el campo no deba ser modificado. Por otro lado, también deberemos asignar a la propiedad del control encargada de visualizar el valor del campo una expresión de enlace a datos, que obtenga dicho valor y lo presente en el control.
<UserControl.Resources>
<Style TargetType="TextBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
</UserControl.Resources>
<!--....-->
<toolkit:DataForm x:Name="frmInvoices"
ItemsSource="{Binding ElementName=ddsInvoices, Path=Data}"
Margin="5">
<toolkit:DataForm.EditTemplate>
<DataTemplate>
<StackPanel>
<toolkit:DataField Label="Código factura:">
<TextBox Text="{Binding Path=InvoiceId, Mode=TwoWay}" Width="40" />
</toolkit:DataField>
<toolkit:DataField Label="Código cliente:">
<TextBox Text="{Binding Path=CustomerId, Mode=TwoWay}" Width="40" />
</toolkit:DataField>
<toolkit:DataField Label="Fecha:">
<sdk:DatePicker SelectedDate="{Binding Path=InvoiceDate, Mode=TwoWay}"
Width="110" HorizontalAlignment="Left" />
</toolkit:DataField>
<toolkit:DataField Label="Dirección:">
<TextBox Text="{Binding Path=BillingAddress, Mode=TwoWay}" Width="150" />
</toolkit:DataField>
<toolkit:DataField Label="Ciudad:">
<TextBox Text="{Binding Path=BillingCity, Mode=TwoWay}" Width="120" />
</toolkit:DataField>
<toolkit:DataField Label="País:">
<TextBox Text="{Binding Path=BillingCountry, Mode=TwoWay}" Width="80" />
</toolkit:DataField>
<toolkit:DataField Label="Importe:">
<TextBox Text="{Binding Path=Total, Mode=TwoWay}" Width="50" />
</toolkit:DataField>
<toolkit:DataField Label="Primera factura?:">
<CheckBox IsChecked="{Binding Path=FirstInvoice, Mode=TwoWay}" />
</toolkit:DataField>
</StackPanel>
</DataTemplate>
</toolkit:DataForm.EditTemplate>
Gracias al uso de la plantilla EditTemplate podemos resolver el conjunto de inconvenientes mencionados en el apartado anterior. En primer lugar, el orden de los campos viene determinado por la posición con la que situemos las etiquetas DataField dentro de la plantilla y no por su nombre; para los títulos de los campos empleamos la propiedad Label del DataField; y para ajustar su tamaño, en el control de edición usamos la propiedad Width combinada con HorizontalAlignment, ésta última establecida como recurso para controles de tipo TextBox, que son la mayoría de los que componen el formulario.
Los controles de edición que estamos utilizando para los campos de la plantilla son iguales a los que emplea el DataForm cuando los genera automáticamente. Sin embargo, si hacemos una rápida revisión de los controles disponibles en la Barra de Herramientas de Visual Studio, podremos deducir que para los valores que deben manejar ciertos campos, el usuario obtendría una experiencia más satisfactoria usando otro tipo de controles más especializados. Este es un tema que tiene la suficiente entidad y amplitud para tratarse por separado, por lo que será abordado en próximos artículos.
Campos no editables
Puesto que el campo InvoiceId tiene activado el atributo Identity en la tabla de la base de datos, su valor es generado por el motor de datos y no debe ser modificado. El control DataForm es consciente de este tipo de situaciones, y por ello, el control TextBox que estamos empleando como campo del formulario no permite ser editado. Este comportamiento se produce porque, internamente, el DataForm está asignando el valor True a la propiedad IsReadOnly del DataField asociado al campo InvoiceId.
También podemos, naturalmente, asignar de forma manual esta propiedad a cualquier otro campo del formulario que necesitemos. A continuación lo vemos aplicado sobre el campo CustomerId.
<toolkit:DataField Label="Código cliente:" IsReadOnly="True">
<TextBox Text="{Binding Path=CustomerId, Mode=TwoWay}" />
</toolkit:DataField>
Una vía alternativa, que será la que utilicemos en el proyecto de ejemplo de este artículo, consiste en emplear un control no editable (TextBlock, Label, etc.) para aquellos campos que no deban ser modificados. En nuestro caso emplearemos un TextBlock para el campo InvoiceId, volviendo a dejar editable el campo CustomerId.
<toolkit:DataField Label="Código factura:">
<TextBlock Text="{Binding Path=InvoiceId, Mode=OneWay}" />
</toolkit:DataField>
Descripción extendida de campo
La posibilidad de que los campos del DataForm dispongan de un texto adicional, explicativo de su contenido, es una característica que podemos lograr a través de la propiedad Description de la etiqueta DataField.
<toolkit:DataField Label="Código factura:" Description="Número de factura">
<TextBox Text="{Binding Path=InvoiceId, Mode=TwoWay}" Width="40" />
</toolkit:DataField>
<toolkit:DataField Label="Código cliente:" Description="Identificador del cliente">
<TextBox Text="{Binding Path=CustomerId, Mode=TwoWay}" Width="40" />
</toolkit:DataField>
<toolkit:DataField Label="Fecha:" Description="Fecha de emisión de la factura">
<sdk:DatePicker SelectedDate="{Binding Path=InvoiceDate, Mode=TwoWay}"
Width="110" HorizontalAlignment="Left" />
</toolkit:DataField>
<toolkit:DataField Label="Dirección:" Description="Dirección de entrega">
<TextBox Text="{Binding Path=BillingAddress, Mode=TwoWay}" Width="150" />
</toolkit:DataField>
<toolkit:DataField Label="Ciudad:" Description="Localidad de entrega">
<TextBox Text="{Binding Path=BillingCity, Mode=TwoWay}" Width="120" />
</toolkit:DataField>
<toolkit:DataField Label="País:" Description="Nacionalidad de entrega">
<TextBox Text="{Binding Path=BillingCountry, Mode=TwoWay}" Width="80" />
</toolkit:DataField>
<toolkit:DataField Label="Importe:" Description="Total a pagar">
<TextBox Text="{Binding Path=Total, Mode=TwoWay}" Width="50" />
</toolkit:DataField>
<toolkit:DataField Label="Primera factura?:" Description="Indica si es la primera vez que se factura al cliente">
<CheckBox IsChecked="{Binding Path=FirstInvoice, Mode=TwoWay}" />
</toolkit:DataField>
Una vez asignada esta propiedad, en tiempo de ejecución aparecerá un icono junto al campo, que mostrará una etiqueta flotante al situar encima el cursor. En el caso de campos de sólo lectura como InvoiceId, esta característica no funciona aunque hayamos asignado valor a la propiedad.
Ubicación de títulos de campo y descripción
Por defecto, el control DataForm sitúa los títulos de los campos a la izquierda del control de edición y los iconos de descripción a la derecha. Sin embargo, este comportamiento puede ser modificado mediante las propiedades LabelPosition y DescriptionViewerPosition, que contienen, respectivamente, un valor de las enumeraciones DataFieldLabelPosition y DataFieldDescriptionViewerPosition, siendo posible, por ejemplo, situar el nombre del campo encima del control de edición del mismo, y el icono de descripción junto al nombre del campo, como vemos en el siguiente bloque de código, en el que también aprovechamos para presentar la propiedad Header, mediante la que asignamos un título al formulario.
<toolkit:DataForm x:Name="frmInvoices"
ItemsSource="{Binding ElementName=ddsInvoices, Path=Data}"
Margin="5"
LabelPosition="Top"
DescriptionViewerPosition="BesideLabel"
Header="Edición de facturas">
Además del control DataForm, estas propiedades también están disponibles para el control DataField, por lo que pueden ser asignadas de forma independiente a cada campo del formulario que necesitemos, como vemos en el siguiente bloque de código.
<toolkit:DataForm.EditTemplate>
<!--....-->
<toolkit:DataField Label="Dirección:" Description="Dirección de entrega" LabelPosition="Top">
<TextBox Text="{Binding Path=BillingAddress, Mode=TwoWay}" Width="150" />
</toolkit:DataField>
<toolkit:DataField Label="Ciudad:" Description="Localidad de entrega" DescriptionViewerPosition="BesideLabel">
<TextBox Text="{Binding Path=BillingCity, Mode=TwoWay}" Width="120" />
</toolkit:DataField>
<toolkit:DataField Label="País:" Description="Nacionalidad de entrega" DescriptionViewerPosition="BesideLabel" LabelPosition="Top">
<TextBox Text="{Binding Path=BillingCountry, Mode=TwoWay}" Width="80" />
</toolkit:DataField>
<!--....-->
</toolkit:DataForm.EditTemplate>
No obstante se trata de un ejemplo extremo, ya que el formulario obtenido resulta un tanto desorganizado.
Llegados a este punto, concluimos la primera parte de este artículo, esperamos que todos aquellos aspectos de edición con el control DataForm comentados hasta el momento os resulten de ayuda e interés.
Un saludo.