Back to Devexpress

Create an Interactive Data-Aware Item for the WinForms Dashboard

dashboard-403032-winforms-dashboard-winforms-designer-ui-elements-and-customization-create-a-custom-item-create-an-interactive-data-aware-item.md

latest34.7 KB
Original Source

Create an Interactive Data-Aware Item for the WinForms Dashboard

  • Aug 31, 2023
  • 13 minutes to read

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:

Create Metadata

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:

NameDescription
DisplayNameAttributeSpecifies a name for a custom item’s icon.
CustomItemDescriptionAttributeSpecifies tooltip text that is displayed for a custom item’s bar in the Ribbon.
CustomItemImageAttributeSpecifies 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:

NameDescription
DisplayNameAttributeSpecifies a data section’s name in the Data Items pane.
EmptyDataItemPlaceholderAttributeSpecifies placeholder text for a pane where you can place a data item.
SupportColoringAttributeSpecifies whether data items in a section support coloring.
SupportInteractivityAttributeSpecifies whether data items in a data section support interactivity.
csharp
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();

    }
}
vb
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

Register a New Metadata Type

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.

csharp
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());
        }
    }
}
vb
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.

Add a Button to the Ribbon

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.

csharp
using System.Windows.Forms;
using DevExpress.DashboardCommon;
using DevExpress.DashboardWin;

namespace TutorialsCustomItems {
public partial class Form1 : Form {
  public Form1(){
      InitializeComponent();
      dashboardDesigner1.CreateRibbon();
      dashboardDesigner1.CreateCustomItemBars();
    }
  }
}
vb
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

Create and Configure a Custom Control

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.

csharp
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;

        }
        // ...
    }
}
vb
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

Add Coloring

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.

csharp
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;
    }
}
vb
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

Configure Interactivity

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.

Master Filtering

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.

csharp
protected override void SetSelection(CustomItemSelection selection){
        chart.ClearSelection();
        foreach (DashboardFlatDataSourceRow item in selection.GetDashboardFlatDataSourceRows(flatData))
            chart.SelectedItems.Add(item);
}
vb
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.

csharp
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;
}
vb
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:

csharp
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;
    }
}
vb
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

Drill-Down

Call the ICustomItemInteractivityProvider.PerformDrillDown(Object) method in a MouseDoubleClick event handler to execute drill down.

csharp
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);
    }
}
vb
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.

csharp
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;
}
vb
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

Update a Custom Control

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.

csharp
// ...
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;
}
vb
' ...
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

Visualize a Custom Item in a Dashboard

Assign the FunnelItemControlProvider object to the e.CustomControlProvider property in a DashboardDesigner.CustomDashboardItemControlCreating event handler to visualize the custom control.

csharp
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>);
        }
    }
}
vb
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

Export a Custom Item

You can export custom dashboard items in the following formats:

  • PDF
  • Image
  • Excel (XLS, XLSX)

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.

csharp
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;
        }
    }
}
vb
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 to See the Result

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.

Next Step

Refer to the following tutorial for more information on how to create a custom Boolean property that manages the Funnel legend’s visibility:

Example

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.

View Example