Creación de un componente en tiempo de diseño de elemento de informe personalizado
Un componente de tiempo de diseño de elemento de informe personalizado es un control que se puede utilizar en el entorno de Visual Studio Report Designer. El componente de tiempo de diseño de elemento de informe personalizado proporciona una superficie de diseño activada que puede aceptar las operaciones de arrastrar y colocar, la integración con el explorador de propiedades de Visual Studio, y la capacidad de proporcionar los editores de propiedades personalizados.
Con un componente de tiempo de diseño de elemento de informe personalizado, el usuario puede colocar un elemento de informe personalizado en un informe en el entorno de diseño, establecer las propiedades de datos personalizadas en el elemento de informe personalizado y, a continuación, guardar el elemento de informe personalizado como parte del proyecto de informe.
El entorno de diseño serializa y deserializa las propiedades que se establecen mediante el componente en tiempo de diseño en tiempo de diseño del entorno de desarrollo. A continuación, las propiedades se almacenan como elementos en el archivo del lenguaje de definición de informes (RDL). Cuando el procesador de informes ejecuta el informe, el procesador de informes pasa las propiedades que se establecen mediante el componente en tiempo de diseño al componente de tiempo de ejecución de un elemento de informe personalizado, que representa el elemento de informe personalizado y lo pasa al procesador de informes.
Nota:
El componente de tiempo de diseño de elemento de informe personalizado se implementa como un componente de Microsoft .NET Framework. En este documento se describirán los detalles de la implementación específicos al componente de tiempo de diseño del elemento de informe personalizado.
Para obtener un ejemplo de un elemento de informe personalizado totalmente implementado, vea Ejemplos del producto SQL Server Reporting Services.
Implementación de un componente en tiempo de diseño
La clase principal de un componente de tiempo de diseño de elemento de informe personalizado se hereda de la clase Microsoft.ReportDesigner.CustomReportItemDesigner. Además de los atributos estándar usados para un control de .NET Framework, la clase de componente debería definir un atributo CustomReportItem. Este atributo debe corresponder al nombre del elemento de informe personalizado como se define en el archivo reportserver.config. Para obtener una lista de atributos de .NET Framework, vea "Atributos" en la documentación del SDK de .NET Framework.
El ejemplo de código siguiente muestra atributos que se aplican a un control de tiempo de diseño del elemento de informe personalizado:
namespace PolygonsCRI
{
[LocalizedName("Polygons")]
[Editor(typeof(CustomEditor), typeof(ComponentEditor))]
[ToolboxBitmap(typeof(PolygonsDesigner),"Polygons.ico")]
[CustomReportItem("Polygons")]
public class PolygonsDesigner : CustomReportItemDesigner
{
...
Inicialización del componente
Las propiedades especificadas por el usuario para un elemento de informe personalizado se pasan utilizando una clase CustomData. La implementación de la clase CustomReportItemDesigner debería reemplazar el método InitializeNewComponent para crear una nueva instancia de la clase CustomData del componente y establecerla en los valores predeterminados.
El ejemplo de código siguiente muestra un ejemplo de una clase de componente de tiempo de diseño de elemento de informe personalizado que reemplaza al método CustomReportItemDesigner.InitializeNewComponent para inicializar la clase CustomData del componente:
public override void InitializeNewComponent()
{
CustomData = new CustomData();
CustomData.DataRowHierarchy = new DataHierarchy();
// Shape grouping
CustomData.DataRowHierarchy.DataMembers.Add(new DataMember());
CustomData.DataRowHierarchy.DataMembers[0].Group = new Group();
CustomData.DataRowHierarchy.DataMembers[0].Group.Name = Name + "_Shape";
CustomData.DataRowHierarchy.DataMembers[0].Group.GroupExpressions.Add(new ReportExpression());
// Point grouping
CustomData.DataRowHierarchy.DataMembers[0].DataMembers.Add(new DataMember());
CustomData.DataRowHierarchy.DataMembers[0].DataMembers[0].Group = new Group();
CustomData.DataRowHierarchy.DataMembers[0].DataMembers[0].Group.Name = Name + "_Point";
CustomData.DataRowHierarchy.DataMembers[0].DataMembers[0].Group.GroupExpressions.Add(new ReportExpression());
// Static column
CustomData.DataColumnHierarchy = new DataHierarchy();
CustomData.DataColumnHierarchy.DataMembers.Add(new DataMember());
// Points
IList<IList<DataValue>> dataValues = new List<IList<DataValue>>();
CustomData.DataRows.Add(dataValues);
CustomData.DataRows[0].Add(new List<DataValue>());
CustomData.DataRows[0][0].Add(NewDataValue("X", ""));
CustomData.DataRows[0][0].Add(NewDataValue("Y", ""));
}
Modificación de las propiedades del componente
Puede modificar las propiedades CustomData en el entorno de diseño de varias maneras. Puede modificar cualquier propiedad expuesta por el componente de tiempo de diseño que esté marcada con el atributo BrowsableAttribute utilizando el explorador de propiedades de Visual Studio. Además, puede modificar las propiedades si arrastra los elementos a la superficie de diseño del elemento de informe personalizado o si hace clic con el botón derecho en el control en el entorno de diseño y selecciona Propiedades en el menú contextual para mostrar una ventana de propiedades personalizada.
El siguiente ejemplo de código muestra una propiedad Microsoft.ReportDesigner.CustomReportItemDesigner.CustomData que tiene aplicado el atributo BrowsableAttribute:
[Browsable(true), Category("Data")]
public string DataSetName
{
get
{
return CustomData.DataSetName;
}
set
{
CustomData.DataSetName = value;
}
}
Puede proporcionar un cuadro de diálogo de editor de propiedades personalizado al componente de tiempo de diseño. La implementación personalizada del editor de propiedades debería heredar de la clase ComponentEditor y debería crear una instancia de un cuadro de diálogo que se puede utilizar para la edición de propiedad.
En el ejemplo siguiente se muestra una implementación de una clase que hereda de ComponentEditor y muestra un cuadro de diálogo de editor de propiedades personalizado:
internal sealed class CustomEditor : ComponentEditor
{
public override bool EditComponent(
ITypeDescriptorContext context, object component)
{
PolygonsDesigner designer = (PolygonsDesigner)component;
PolygonProperties dialog = new PolygonProperties();
dialog.m_designerComponent = designer;
DialogResult result = dialog.ShowDialog();
if (result == DialogResult.OK)
{
designer.Invalidate();
designer.ChangeService().OnComponentChanged(designer, null, null, null);
return true;
}
else
return false;
}
}
El cuadro de diálogo de editor de propiedades personalizado puede invocar al editor de expresiones del diseñador de informes. En el ejemplo siguiente, el editor de expresiones se invoca cuando el usuario selecciona el primer elemento del cuadro combinado:
private void EditableCombo_SelectedIndexChanged(object sender,
EventArgs e)
{
ComboBox combo = (ComboBox)sender;
if (combo.SelectedIndex == 0 && m_launchEditor)
{
m_launchEditor = false;
ExpressionEditor editor = new ExpressionEditor();
string newValue;
newValue = (string)editor.EditValue(null, m_designerComponent.Site, m_oldComboValue);
combo.Items[0] = newValue;
}
}
Uso de verbos de diseñador
Un verbo de diseñador es un comando de menú vinculado a un controlador de eventos. Puede agregar verbos de diseñador que aparecen en el menú contextual de un componente cuando se usa el control en tiempo de ejecución del elemento de informe personalizado en el entorno de diseño. Puede devolver la lista de verbos de diseñador disponibles desde el componente de tiempo de ejecución con la propiedad Verbs.
En el DesignerVerbCollectionejemplo de código siguiente se muestra un verbo del diseñador y un controlador de eventos que se agrega a . En el ejemplo también se muestra el código del controlador de eventos:
public override DesignerVerbCollection Verbs
{
get
{
if (m_verbs == null)
{
m_verbs = new DesignerVerbCollection();
m_verbs.Add(new DesignerVerb("Proportional Scaling", new EventHandler(OnProportionalScaling)));
m_verbs[0].Checked = (GetCustomProperty("poly:Proportional") == bool.TrueString);
}
return m_verbs;
}
}
private void OnProportionalScaling(object sender, EventArgs e)
{
bool proportional = !
(GetCustomProperty("poly:Proportional") == bool.TrueString);
m_verbs[0].Checked = proportional;
SetCustomProperty("poly:Proportional", proportional.ToString());
ChangeService().OnComponentChanged(this, null, null, null);
Invalidate();
}
Uso de adornos
Las clases de elemento de informe personalizado también pueden implementar una clase Microsoft.ReportDesigner.Design.Adornment. Una opción gráfica permite al control de elemento de informe personalizado proporcionar las áreas fuera del rectángulo principal de la superficie de diseño. Estas áreas pueden administrar los eventos de interfaz de usuario, como los clics del mouse y las operaciones de arrastrar y colocar. La clase Adornment que se define en el espacio de nombres Microsoft.ReportDesigner de Reporting Services es una implementación de tránsito de la clase Adorner de Windows Forms. Para obtener la documentación completa de la clase Adorner, vea Información general sobre servicios de comportamiento en MSDN Library. Para obtener el código de ejemplo que implementa una clase Microsoft.ReportDesigner.Design.Adornment, vea Ejemplos del producto SQL Server Reporting Services.
Para obtener más información sobre la programación y el uso de Windows Forms en Visual Studio, consulte estos artículos en MSDN Library:
Atributos de tiempo de diseño para componentes
Componentes en Visual Studio
Tutorial: Crear un control de Windows Forms que aproveche las características de tiempo de diseño de Visual Studio