dashboard-403032-winforms-dashboard-winforms-designer-ui-elements-and-customization-create-a-custom-item-create-an-interactive-data-aware-item.md
This tutorial shows you how to embed additional functionality, such as export, coloring, and interactivity in a custom item. In the previous tutorial you bound a custom item to data. In this tutorial, you will enable master filtering and drill-down interactivity, coloring, and export in the Funnel custom item.
First, create a WinForms Dashboard project and create the CustomItems folder in it to store custom item data. Then, follow the instructions below:
Metadata is a CustomItemMetadata descendant that describes options and settings available to a user in the UI. Register the metadata object to be able to create custom items of this type. The structure you specified in metadata defines these custom items in a dashboard definition.
Add a new class called FunnelItemMetadata.cs to the CustomItems folder in your project. In the file, derive a class from CustomItemMetadata and declare its properties that correspond to data sections in the binding panel. The Value property allows you to add an individual data item to the section. The Arguments collection property allows you to add several data items.
Apply the following class attributes to FunnelItemMetadata:
| Name | Description |
|---|---|
| DisplayNameAttribute | Specifies a name for a custom item’s icon. |
| CustomItemDescriptionAttribute | Specifies tooltip text that is displayed for a custom item’s bar in the Ribbon. |
| CustomItemImageAttribute | Specifies an icon for a custom item’s bar in the Ribbon. |
Add an SVG file you want to use as a custom item’s icon to the Images folder in your project. You can use SVG images from the example: WinForms Dashboard - Custom Items. Make sure an SVG file’s Build Action property is set to Embedded Resource.
Apply the following attributes to FunnelItemMetadata’s properties:
| Name | Description |
|---|---|
| DisplayNameAttribute | Specifies a data section’s name in the Data Items pane. |
| EmptyDataItemPlaceholderAttribute | Specifies placeholder text for a pane where you can place a data item. |
| SupportColoringAttribute | Specifies whether data items in a section support coloring. |
| SupportInteractivityAttribute | Specifies whether data items in a data section support interactivity. |
using System.ComponentModel;
using DevExpress.DashboardCommon;
namespace TutorialsCustomItems {
[DisplayName("Funnel"),
CustomItemDescription("Funnel description"),
CustomItemImage("TutorialsCustomItems.Images.Funnel.svg")]
public class FunnelItemMetadata : CustomItemMetadata {
[DisplayName("Value"),
EmptyDataItemPlaceholder("Value"),
SupportColoring(DefaultColoringMode.None)]
public Measure Value {
get { return GetPropertyValue<Measure>(); }
set { SetPropertyValue(value); }
}
[DisplayName("Arguments"),
EmptyDataItemPlaceholder("My Argument"),
SupportColoring(DefaultColoringMode.Hue),
SupportInteractivity]
public DimensionCollection Arguments { get; } = new DimensionCollection();
}
}
Imports System.ComponentModel
Imports DevExpress.DashboardCommon
Namespace TutorialsCustomItems
<DisplayName("Funnel"), CustomItemDescription("Funnel description"), CustomItemImage("Funnel.svg")>
Public Class FunnelItemMetadata
Inherits CustomItemMetadata
<DisplayName("Value"), EmptyDataItemPlaceholder("Value"), SupportColoring(DefaultColoringMode.None)>
Public Property Value() As Measure
Get
Return GetPropertyValue(Of Measure)()
End Get
Set(ByVal value As Measure)
SetPropertyValue(value)
End Set
End Property
<DisplayName("Arguments"), EmptyDataItemPlaceholder("My Argument"), SupportColoring(DefaultColoringMode.Hue), SupportInteractivity>
Public ReadOnly Property Arguments() As New DimensionCollection()
End Class
End Namespace
Call the CustomItemMetadataTypes.Register<T>() method before the main application form is created to allow the Dashboard Designer to read custom item data from a dashboard. Pass a new metadata type to the method. The metadata type is stored in the CustomItemMetadataTypes collection corresponds to the FunnelItemMetadata class.
using DevExpress.XtraEditors;
using System;
using System.Windows.Forms;
using DevExpress.DashboardCommon;
using TutorialsCustomItems.CustomItems;
namespace TutorialsCustomItems {
static class Program{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(){
// ...
Dashboard.CustomItemMetadataTypes.Register<FunnelItemMetadata>();
Application.Run(new Form1());
}
}
}
Imports DevExpress.XtraEditors
Imports System
Imports System.Windows.Forms
Imports DevExpress.DashboardCommon
Imports TutorialsCustomItems.CustomItems
Namespace TutorialsCustomItems
Friend NotInheritable Class Program
''' <summary>
''' The main entry point for the application.
''' </summary>
Private Sub New()
End Sub
<STAThread> _
Shared Sub Main()
' ...
Dashboard.CustomItemMetadataTypes.Register(Of FunnelItemMetadata)()
Application.Run(New Form1())
End Sub
End Class
End Namespace
The Dashboard Designer automatically creates a binding panel based on metadata for the custom item.
Call the DashboardDesigner.CreateCustomItemBars(Type[]) method to insert a custom item’s bar in the Ribbon. Click the bar to create a custom item in the Dashboard Designer at runtime.
using System.Windows.Forms;
using DevExpress.DashboardCommon;
using DevExpress.DashboardWin;
namespace TutorialsCustomItems {
public partial class Form1 : Form {
public Form1(){
InitializeComponent();
dashboardDesigner1.CreateRibbon();
dashboardDesigner1.CreateCustomItemBars();
}
}
}
Imports System.Windows.Forms
Imports DevExpress.DashboardCommon
Imports DevExpress.DashboardWin
Namespace TutorialsCustomItems
Partial Public Class Form1
Inherits Form
Public Sub New()
InitializeComponent()
dashboardDesigner1.CreateRibbon()
dashboardDesigner1.CreateCustomItemBars()
End Sub
End Class
End Namespace
A custom control displays a custom item in a dashboard. To configure the custom control, add the FunnelItemControlProvider.cs file to the CustomItems folder. In the file, derive the FunnelItemControlProvider class from CustomControlProviderBase. FunnelItemControlProvider creates and updates the control based on data that a dashboard transfers to the object.
The CustomControlProviderBase.Control property gets the control that displays the custom item.
Event subscriptions are used for further customization.
using System.Windows.Forms;
using DevExpress.DashboardCommon;
using DevExpress.DashboardWin;
using DevExpress.XtraCharts;
using DevExpress.XtraReports.UI;
using System.Linq;
namespace TutorialsCustomItems {
public class FunnelItemControlProvider : CustomControlProviderBase {
CustomDashboardItem<FunnelItemMetadata> dashboardItem;
ChartControl chart;
DashboardFlatDataSource flatData;
protected override Control Control { get { return chart; } }
public FunnelItemControlProvider(CustomDashboardItem<FunnelItemMetadata> dashboardItem) {
this.dashboardItem = dashboardItem;
chart = new ChartControl();
chart.RuntimeHitTesting = true;
chart.BorderOptions.Visibility = DevExpress.Utils.DefaultBoolean.False;
chart.SeriesSelectionMode = SeriesSelectionMode.Point;
chart.MouseDoubleClick += MouseDoubleClick;
chart.SelectedItemsChanged += ChartSelectedItemsChanged;
chart.SelectedItemsChanging += ChartSelectedItemsChanging;
chart.CustomDrawSeriesPoint += CustomDrawSeriesPoint;
}
// ...
}
}
Imports System.Windows.Forms
Imports DevExpress.DashboardCommon
Imports DevExpress.DashboardWin
Imports DevExpress.XtraCharts
Imports DevExpress.XtraReports.UI
Imports System.Linq
Namespace TutorialsCustomItems
Public Class FunnelItemControlProvider
Inherits CustomControlProviderBase
Private dashboardItem As CustomDashboardItem(Of FunnelItemMetadata)
Private chart As ChartControl
Private flatData As DashboardFlatDataSource
Protected Overrides ReadOnly Property Control() As Control
Get
Return chart
End Get
End Property
Public Sub New(ByVal dashboardItem As CustomDashboardItem(Of FunnelItemMetadata))
Me.dashboardItem = dashboardItem
chart = New ChartControl()
chart.RuntimeHitTesting = True
chart.BorderOptions.Visibility = DevExpress.Utils.DefaultBoolean.False
chart.SeriesSelectionMode = SeriesSelectionMode.Point
chart.MouseDoubleClick += MouseDoubleClick
chart.SelectedItemsChanged += ChartSelectedItemsChanged
chart.SelectedItemsChanging += ChartSelectedItemsChanging
chart.CustomDrawSeriesPoint += CustomDrawSeriesPoint
End Sub
' ...
End Class
End Namespace
SupportColoringAttribute identifies that the Funnel item can use coloring. When you get DashboardFlatDataSource, you can include color values calculated for each data row. To accomplish this, set the DashboardFlatDataSourceOptions.AddColoringColumns to true and pass the DashboardFlatDataSourceOptions object to the CustomItemData.GetFlatData(DashboardFlatDataSourceOptions) method. Then, you can use the DashboardFlatDataSource.GetColoringColumn(String) method to bind the column to Funnel chart series.
public class FunnelItemControlProvider : CustomControlProviderBase {
DashboardFlatDataSource flatData;
// ...
protected override void UpdateControl(CustomItemData customItemData){
// ...
flatData = customItemData.GetFlatData(new DashboardFlatDataSourceOptions() { AddColoringColumns = true });
Series series = ConfigureSeries(flatData);
chart.Series.Add(series);
}
Series ConfigureSeries(DashboardFlatDataSource flatData){
Series series = new Series("A Funnel Series", ViewType.Funnel);
if (dashboardItem.Metadata.Value != null && dashboardItem.Metadata.Arguments.Count > 0){
series.DataSource = flatData;
series.ValueDataMembers.AddRange(dashboardItem.Metadata.Value.UniqueId);
if (Interactivity.IsDrillDownEnabled){
int drillDownLevel = Interactivity.GetCurrentDrillDownValues().Count;
series.ArgumentDataMember = dashboardItem.Metadata.Arguments[drillDownLevel].UniqueId;
}
else
series.ArgumentDataMember = dashboardItem.Metadata.Arguments.Last().UniqueId;
series.ColorDataMember = flatData.GetColoringColumn(dashboardItem.Metadata.Value.UniqueId).Name;
}
((FunnelSeriesLabel)series.Label).Position = FunnelSeriesLabelPosition.Center;
FunnelSeriesView seriesView = series.View as FunnelSeriesView;
return series;
}
}
Public Class FunnelItemControlProvider
Inherits CustomControlProviderBase
Private flatData As DashboardFlatDataSource
' ...
Protected Overrides Sub UpdateControl(ByVal customItemData As CustomItemData)
' ...
flatData = customItemData.GetFlatData(New DashboardFlatDataSourceOptions() With {.AddColoringColumns = True})
Dim series As Series = ConfigureSeries(flatData)
chart.Series.Add(series)
End Sub
Private Function ConfigureSeries(ByVal flatData As DashboardFlatDataSource) As Series
Dim series As New Series("A Funnel Series", ViewType.Funnel)
If dashboardItem.Metadata.Value IsNot Nothing AndAlso dashboardItem.Metadata.Arguments.Count > 0 Then
series.DataSource = flatData
series.ValueDataMembers.AddRange(dashboardItem.Metadata.Value.UniqueId)
If Interactivity.IsDrillDownEnabled Then
Dim drillDownLevel As Integer = Interactivity.GetCurrentDrillDownValues().Count
series.ArgumentDataMember = dashboardItem.Metadata.Arguments(drillDownLevel).UniqueId
Else
series.ArgumentDataMember = dashboardItem.Metadata.Arguments.Last().UniqueId
End If
series.ColorDataMember = flatData.GetColoringColumn(dashboardItem.Metadata.Value.UniqueId).Name
End If
CType(series.Label, FunnelSeriesLabel).Position = FunnelSeriesLabelPosition.Center
Dim seriesView As FunnelSeriesView = TryCast(series.View, FunnelSeriesView)
Return series
End Function
End Class
SupportInteractivityAttribute identifies that you can make the Funnel item interactive. To do this, you need to configure master filtering and drill down in the FunnelItemControlProvider class.
Override the CustomControlProviderBase.SetSelection(CustomItemSelection) method to update a custom control according to the current master filter selection. The method is called each time a master filter selection changes.
protected override void SetSelection(CustomItemSelection selection){
chart.ClearSelection();
foreach (DashboardFlatDataSourceRow item in selection.GetDashboardFlatDataSourceRows(flatData))
chart.SelectedItems.Add(item);
}
Protected Overrides Sub SetSelection(ByVal selection As CustomItemSelection)
chart.ClearSelection()
For Each item As DashboardFlatDataSourceRow In selection.GetDashboardFlatDataSourceRows(flatData)
chart.SelectedItems.Add(item)
Next item
End Sub
In this tutorial, we use the CustomControlProviderBase.Interactivity property with its methods to set the master filter in a ChartSelectionChanged event handler. The ChartSelectedItemsChanged event occurs every time you click on the Funnel’s value in the UI. The ICustomItemInteractivityProvider.SetMasterFilter(Object) method sets a new selected value, and the SetSelection method is called once the value is changed.
void ChartSelectedItemsChanged(object sender, SelectedItemsChangedEventArgs e){
if (chart.SelectedItems.Count == 0 && Interactivity.CanClearMasterFilter)
Interactivity.ClearMasterFilter();
else if (Interactivity.CanSetMasterFilter)
Interactivity.SetMasterFilter(chart.SelectedItems.OfType<DashboardFlatDataSourceRow>());
}
void ChartSelectedItemsChanging(object sender, SelectedItemsChangingEventArgs e){
if (Interactivity.MasterFilterMode == DashboardItemMasterFilterMode.Single && e.NewItems.OfType<DashboardFlatDataSourceRow>().Count() == 0)
e.Cancel = true;
}
Private Sub ChartSelectedItemsChanged(ByVal sender As Object, ByVal e As SelectedItemsChangedEventArgs)
If chart.SelectedItems.Count = 0 AndAlso Interactivity.CanClearMasterFilter Then
Interactivity.ClearMasterFilter()
ElseIf Interactivity.CanSetMasterFilter Then
Interactivity.SetMasterFilter(chart.SelectedItems.OfType(Of DashboardFlatDataSourceRow)())
End If
End Sub
Private Sub ChartSelectedItemsChanging(ByVal sender As Object, ByVal e As SelectedItemsChangingEventArgs)
If Interactivity.MasterFilterMode = DashboardItemMasterFilterMode.Single AndAlso e.NewItems.OfType(Of DashboardFlatDataSourceRow)().Count() = 0 Then
e.Cancel = True
End If
End Sub
The Clear Master Filter button also calls the SetSelection method.
To update the ChartControl.SelectionMode property according to the actual master filter mode, use the following code:
void UpdateSelectionMode(){
switch (Interactivity.MasterFilterMode){
case DashboardItemMasterFilterMode.Single:
chart.SelectionMode = ElementSelectionMode.Single;
break;
case DashboardItemMasterFilterMode.Multiple:
chart.SelectionMode = ElementSelectionMode.Extended;
break;
default:
chart.SelectionMode = ElementSelectionMode.None;
break;
}
}
Private Sub UpdateSelectionMode()
Select Case Interactivity.MasterFilterMode
Case DashboardItemMasterFilterMode.Single
chart.SelectionMode = ElementSelectionMode.Single
Case DashboardItemMasterFilterMode.Multiple
chart.SelectionMode = ElementSelectionMode.Extended
Case Else
chart.SelectionMode = ElementSelectionMode.None
End Select
End Sub
The master filter initial behavior depends on the selected mode.
Multiple
Single
Call the ICustomItemInteractivityProvider.PerformDrillDown(Object) method in a MouseDoubleClick event handler to execute drill down.
void MouseDoubleClick(object sender, MouseEventArgs e){
ChartHitInfo hitInfo = chart.CalcHitInfo(e.Location);
if (hitInfo.InSeriesPoint){
if (Interactivity.CanPerformDrillDown)
Interactivity.PerformDrillDown(hitInfo.SeriesPoint.Tag as DashboardFlatDataSourceRow);
}
}
Private Sub MouseDoubleClick(ByVal sender As Object, ByVal e As MouseEventArgs)
Dim hitInfo As ChartHitInfo = chart.CalcHitInfo(e.Location)
If hitInfo.InSeriesPoint Then
If Interactivity.CanPerformDrillDown Then
Interactivity.PerformDrillDown(TryCast(hitInfo.SeriesPoint.Tag, DashboardFlatDataSourceRow))
End If
End If
End Sub
The Dashboard Designer does not calculate data item values that do not fall into the current drill-down level.
The ICustomItemInteractivityProvider.GetCurrentDrillDownValues() method is used to determine the current drill-down level. A Dashboard displays the last data item in the Argument section, if drill-down is disabled.
Series ConfigureSeries(DashboardFlatDataSource flatData){
Series series = new Series("A Funnel Series", ViewType.Funnel);
if (dashboardItem.Metadata.Value != null && dashboardItem.Metadata.Arguments.Count > 0){
series.DataSource = flatData;
series.ValueDataMembers.AddRange(dashboardItem.Metadata.Value.UniqueId);
if (Interactivity.IsDrillDownEnabled){
int drillDownLevel = Interactivity.GetCurrentDrillDownValues().Count;
series.ArgumentDataMember = dashboardItem.Metadata.Arguments[drillDownLevel].UniqueId;
}
else
series.ArgumentDataMember = dashboardItem.Metadata.Arguments.Last().UniqueId;
series.ColorDataMember = flatData.GetColoringColumn(dashboardItem.Metadata.Value.UniqueId).Name;
}
((FunnelSeriesLabel)series.Label).Position = FunnelSeriesLabelPosition.Center;
return series;
}
Private Function ConfigureSeries(ByVal flatData As DashboardFlatDataSource) As Series
Dim series As New Series("A Funnel Series", ViewType.Funnel)
If dashboardItem.Metadata.Value IsNot Nothing AndAlso dashboardItem.Metadata.Arguments.Count > 0 Then
series.DataSource = flatData
series.ValueDataMembers.AddRange(dashboardItem.Metadata.Value.UniqueId)
If Interactivity.IsDrillDownEnabled Then
Dim drillDownLevel As Integer = Interactivity.GetCurrentDrillDownValues().Count
series.ArgumentDataMember = dashboardItem.Metadata.Arguments(drillDownLevel).UniqueId
Else
series.ArgumentDataMember = dashboardItem.Metadata.Arguments.Last().UniqueId
End If
series.ColorDataMember = flatData.GetColoringColumn(dashboardItem.Metadata.Value.UniqueId).Name
End If
CType(series.Label, FunnelSeriesLabel).Position = FunnelSeriesLabelPosition.Center
Return series
End Function
The CustomControlProviderBase.UpdateControl(CustomItemData) method is called each time the custom item’s data or settings change. The method supplies data for the custom item based on measures and dimensions that are specified in metadata. Call the CustomItemData.GetFlatData() method to get custom item data and bind it to the control.
The CustomDrawSeriesPoint event formats text values of labels and legend.
// ...
protected override void UpdateControl(CustomItemData customItemData){
UpdateSelectionMode();
flatData = customItemData.GetFlatData(new DashboardFlatDataSourceOptions() { AddColoringColumns = true });
chart.Series.Clear();
Series series = ConfigureSeries(flatData);
chart.Series.Add(series);
}
Series ConfigureSeries(DashboardFlatDataSource flatData){
Series series = new Series("A Funnel Series", ViewType.Funnel);
if (dashboardItem.Metadata.Value != null && dashboardItem.Metadata.Arguments.Count > 0){
series.DataSource = flatData;
series.ValueDataMembers.AddRange(dashboardItem.Metadata.Value.UniqueId);
if (Interactivity.IsDrillDownEnabled){
int drillDownLevel = Interactivity.GetCurrentDrillDownValues().Count;
series.ArgumentDataMember = dashboardItem.Metadata.Arguments[drillDownLevel].UniqueId;
}
else
series.ArgumentDataMember = dashboardItem.Metadata.Arguments.Last().UniqueId;
series.ColorDataMember = flatData.GetColoringColumn(dashboardItem.Metadata.Value.UniqueId).Name;
}
((FunnelSeriesLabel)series.Label).Position = FunnelSeriesLabelPosition.Center;
return series;
}
void CustomDrawSeriesPoint(object sender, CustomDrawSeriesPointEventArgs e){
DashboardFlatDataSourceRow row = e.SeriesPoint.Tag as DashboardFlatDataSourceRow;
string formattedValue = flatData.GetDisplayText(dashboardItem.Metadata.Value.UniqueId, row);
e.LabelText = e.SeriesPoint.Argument + " - " + formattedValue;
e.LegendText = e.SeriesPoint.Argument;
}
' ...
Protected Overrides Sub UpdateControl(ByVal customItemData As CustomItemData)
UpdateSelectionMode()
flatData = customItemData.GetFlatData(New DashboardFlatDataSourceOptions() With {.AddColoringColumns = True})
chart.Series.Clear()
Dim series As Series = ConfigureSeries(flatData)
chart.Series.Add(series)
End Sub
Private Function ConfigureSeries(ByVal flatData As DashboardFlatDataSource) As Series
Dim series As New Series("A Funnel Series", ViewType.Funnel)
If dashboardItem.Metadata.Value IsNot Nothing AndAlso dashboardItem.Metadata.Arguments.Count > 0 Then
series.DataSource = flatData
series.ValueDataMembers.AddRange(dashboardItem.Metadata.Value.UniqueId)
If Interactivity.IsDrillDownEnabled Then
Dim drillDownLevel As Integer = Interactivity.GetCurrentDrillDownValues().Count
series.ArgumentDataMember = dashboardItem.Metadata.Arguments(drillDownLevel).UniqueId
Else
series.ArgumentDataMember = dashboardItem.Metadata.Arguments.Last().UniqueId
End If
series.ColorDataMember = flatData.GetColoringColumn(dashboardItem.Metadata.Value.UniqueId).Name
End If
CType(series.Label, FunnelSeriesLabel).Position = FunnelSeriesLabelPosition.Center
Return series
End Function
Private Sub CustomDrawSeriesPoint(ByVal sender As Object, ByVal e As CustomDrawSeriesPointEventArgs)
Dim row As DashboardFlatDataSourceRow = TryCast(e.SeriesPoint.Tag, DashboardFlatDataSourceRow)
Dim formattedValue As String = flatData.GetDisplayText(dashboardItem.Metadata.Value.UniqueId, row)
e.LabelText = e.SeriesPoint.Argument & " - " & formattedValue
e.LegendText = e.SeriesPoint.Argument
End Sub
Assign the FunnelItemControlProvider object to the e.CustomControlProvider property in a DashboardDesigner.CustomDashboardItemControlCreating event handler to visualize the custom control.
using System.Windows.Forms;
using TutorialsCustomItems.CustomItems;
using DevExpress.DashboardCommon;
using DevExpress.DashboardWin;
namespace TutorialsCustomItems {
public partial class Form1 : Form {
dashboardDesigner1.CustomDashboardItemControlCreating += DashboardDesigner1_CustomDashboardItemControlCreating;
// ...
private void DashboardDesigner1_CustomDashboardItemControlCreating(object sender,
CustomDashboardItemControlCreatingEventArgs e){
if (e.MetadataType == typeof(FunnelItemMetadata))
e.CustomControlProvider = new FunnelItemControlProvider(dashboardDesigner1.Dashboard.Items[e.DashboardItemName] as CustomDashboardItem<FunnelItemMetadata>);
}
}
}
Imports System.Windows.Forms
Imports TutorialsCustomItems.CustomItems
Imports DevExpress.DashboardCommon
Imports DevExpress.DashboardWin
Namespace TutorialsCustomItems
Partial Public Class Form1
Inherits Form
dashboardDesigner1.CustomDashboardItemControlCreating += DashboardDesigner1_CustomDashboardItemControlCreating
' ...
Private Sub DashboardDesigner1_CustomDashboardItemControlCreating(ByVal sender As Object, ByVal e As CustomDashboardItemControlCreatingEventArgs)
If e.MetadataType Is GetType(FunnelItemMetadata) Then
e.CustomControlProvider = New FunnelItemControlProvider(TryCast(dashboardDesigner1.Dashboard.Items(e.DashboardItemName), CustomDashboardItem(Of FunnelItemMetadata)))
End If
End Sub
End Class
End Namespace
You can export custom dashboard items in the following formats:
Refer to the following help topic for more information on how to configure export of custom dashboard items to different formats: Custom Item Export.
To export the custom Funnel item to Image or PDF, override the CustomControlProviderBase.GetPrintableControl method to obtain the printable control.
using DevExpress.XtraReports.UI;
using DevExpress.DashboardCommon;
namespace TutorialsCustomItems {
public class FunnelItemControlProvider : CustomControlProviderBase {
protected override XRControl GetPrintableControl(CustomItemData customItemData, CustomItemExportInfo info) {
PrintableComponentContainer container = new PrintableComponentContainer();
container.PrintableComponent = chart;
return container;
}
}
}
Imports DevExpress.XtraReports.UI
Imports DevExpress.DashboardCommon
Namespace TutorialsCustomItems
Public Class FunnelItemControlProvider
Inherits CustomControlProviderBase
Protected Overrides Function GetPrintableControl(ByVal customItemData As CustomItemData, ByVal info As CustomItemExportInfo) As XRControl
Dim container As New PrintableComponentContainer()
container.PrintableComponent = chart
Return container
End Function
End Class
End Namespace
Run the project and click the Funnel button in the Ribbon to add the custom item to the dashboard:
This action adds the custom item to the dashboard’s layout:
Drag data fields from the Data Source Browser and drop them onto the appropriate section in the binding panel to supply the custom item with data.
Refer to the following tutorial for more information on how to create a custom Boolean property that manages the Funnel legend’s visibility:
The following example shows how to implement a custom dashboard item in a WinForms application. The example contains custom items that you get once the tutorials are completed. You can find the Funnel item’s source code in this project.