Criando um componente de tempo de design de item de relatório personalizado
Um componente em tempo de design de item de relatório personalizado é um controle que pode ser usado no ambiente do Designer de Relatórios do Visual Studio. O componente em tempo de design de item de relatório personalizado oferece uma superfície de design ativada que pode aceitar operações de arrastar e soltar, a integração ao pesquisador de propriedade Visual Studio e a capacidade de oferecer editores de propriedade personalizados.
Com um componente em tempo de design de item de relatório personalizado, o usuário pode posicionar um item de relatório personalizado em um relatório no ambiente de design, definir propriedades de dados personalizadas no item de relatório personalizado e, depois, salvar esse item como parte do projeto de relatório.
As propriedades definidas usando o componente em tempo de design no ambiente de desenvolvimento são serializadas e desserializadas pelo ambiente de design de host e, depois, armazenadas como elementos no arquivo em linguagem RDL. Quando o relatório é executado pelo processador de relatório, as propriedades definidas usando o componente em tempo de design são passadas pelo processador de relatório para um componente em tempo de execução de item de relatório personalizado, que renderiza o item de relatório personalizado e o devolve ao processador de relatório.
Observação |
---|
O componente em tempo de design de item de relatório personalizado que é implementado como um componente Microsoft.NET Framework. Este documento descreverá detalhes de implementação específicos do componente em tempo de design de item de relatório personalizado. Para obter mais informações sobre o desenvolvimento de componentes usando o .NET Framework, consulte a seção sobre Componentes do Visual Studio na biblioteca MSDN. |
Implementando um componente em tempo de design
A classe principal de um componente em tempo de design de item de relatório personalizado que é herdada da classe Microsoft.ReportDesigner.CustomReportItemDesigner. Além dos atributos padrão usados para um controle .NET Framework, sua classe de componente deve definir um atributo CustomReportItem. Esse atributo deve corresponder ao nome do item de relatório personalizado conforme definido no arquivo reportserver.config. Para obter uma lista de atributos do .NET Framework, consulte Atributos na documentação do .NET Framework SDK.
O seguinte exemplo de código mostra atributos que estão sendo aplicados a um controle em tempo de design de item de relatório personalizado:
namespace PolygonsCRI
{
[LocalizedName("Polygons")]
[Editor(typeof(CustomEditor), typeof(ComponentEditor))]
[ToolboxBitmap(typeof(PolygonsDesigner),"Polygons.ico")]
[CustomReportItem("Polygons")]
public class PolygonsDesigner : CustomReportItemDesigner
{
...
Inicializando o componente
Você passa propriedades especificadas pelo usuário para um item de relatório personalizado usando uma classe Microsoft.ReportDesigner.CustomData. Sua implementação da classe CustomReportItemDesigner deve substituir o método InitializeNewComponent para criar uma nova instância da classe CustomData do seu componente e defini-la com valores padrão.
O seguinte exemplo de código mostra um exemplo de uma classe de componente em tempo de design de item de relatório personalizado que substitui o método CustomReportItemDesigner.InitializeNewComponent para inicializar a classe CustomData do 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", ""));
}
Modificando propriedades do componente
Você pode modificar propriedades CustomData no ambiente de design de diversas maneiras. Você pode modificar quaisquer propriedades expostas pelo componente em tempo de design que estejam marcadas com o atributo BrowsableAttribute usando o pesquisador de propriedade do Visual Studio. Além disso, você pode modificar propriedades arrastando itens para a superfície de design do item de relatório personalizado, ou clicando com o botão direito no controle do ambiente de design e selecionando Propriedades no menu de atalho para exibir uma janela de propriedades personalizadas.
O seguinte exemplo de código mostra uma propriedade Microsoft.ReportDesigner.CustomData que tem o atributo BrowsableAttribute aplicado:
[Browsable(true), Category("Data")]
public string DataSetName
{
get
{
return CustomData.DataSetName;
}
set
{
CustomData.DataSetName = value;
}
}
Você pode fornecer ao componente em tempo de design uma caixa de diálogo de editor de propriedades personalizadas. A implementação do editor de propriedades personalizadas deve ser herdada da classe ComponentEditor e deve criar uma instância de uma caixa de diálogo a ser usada na edição de propriedades.
O seguinte exemplo mostra uma implementação de uma classe herdada de ComponentEditor e exibe uma caixa de diálogo de editor de propriedade personalizadas:
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;
}
}
Sua caixa de diálogo de editor de propriedades personalizadas pode invocar o Editor de Expressão do Designer de Relatórios. Neste exemplo, o Editor de Expressão é invocado quando o usuário seleciona o primeiro elemento na caixa de combinação:
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;
}
}
Usando verbos do designer
Um verbo do designer é um comando de menu vinculado a um manipulador de eventos. Você pode adicionar verbos do designer que aparecerão no menu de atalho de um componente quando o controle em tempo de execução do seu item de relatório personalizado estiver sendo usado no ambiente de design. Você pode retornar a lista de verbos do designer disponíveis de seu componente em tempo de execução usando a propriedade Verbs.
Este exemplo de código mostra um verbo do designer e um manipulador de eventos que está sendo adicionado ao DesignerVerbCollection, bem como o código do manipulador 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();
}
Usando adornos
Classes de item de relatório personalizadas também podem implementar uma classe Microsoft.ReportDesigner.Design.Adornment. Um adorno permite que o controle de item de relatório personalizado forneça áreas fora do retângulo principal da superfície de design. Essas áreas podem tratar eventos de interface do usuário, tais como cliques de mouse e operações de arrastar e soltar. A classe Adornment que é definida no namespace Reporting ServicesMicrosoft.ReportDesigner é uma implementação de passagem da classe Adorner localizada no Windows Forms. Para obter a documentação completa da classe Adorner, consulte a seção sobre Visão geral do serviço de comportamento na biblioteca MSDN. Para obter um código de exemplo que implementa uma classe Microsoft.ReportDesigner.Design.Adornment, consulte SQL Server Reporting Services Product Samples (em inglês).
Para obter mais informações sobre como programar e usar o Windows Forms no Visual Studio, consulte estes tópicos na biblioteca MSDN:
Atributos em tempo de design para componentes
Componentes do Visual Studio
Passo a passo: Criando um controle do Windows Forms que aproveita recursos em tempo de design do Visual Studio