xtrareports-3307-feature-guide-to-devexpress-reports-use-report-controls-use-custom-controls-extend-existing-report-control.md
Do the following to implement a custom control based on an existing report control:
The example below describes how to add a new Number property to the XRLabel control to limit the values that control can accept to numbers only.
View Example: Create a Custom Numeric Label
Numericlabel.svg file, add it to the project, and set the Build Action to Embedded Resource.Add a new NumericLabel.cs file to the project with the following content:
using DevExpress.Utils.Serializing;
using DevExpress.XtraReports;
using DevExpress.XtraReports.UI;
using System.ComponentModel;
using DevExpress.XtraReports.Expressions;
using DevExpress.Utils.Design;
namespace WinFormsApp_CustomNumericLabel {
[ToolboxItem(true)]
[DefaultBindableProperty("Number")]
[ToolboxSvgImage("WinFormsApp_CustomNumericLabel.NumericLabel.svg, WinFormsApp_CustomNumericLabel")]
public class NumericLabel : XRLabel {
[DefaultValue(0)]
[XtraSerializableProperty]
public int Number { get; set; }
// Set the "Browsable" and "EditorBrowsable" attributes to "false" and "Never"
// to hide the "Text" property from the "Properties" window and editor (IntelliSense).
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public override string Text {
get { return Number.ToString(); }
set {
int i;
Number = (int.TryParse(value, out i)) ? i : 0;
}
}
// Implement a static constructor as shown below to add
// the "Number" property to the property grid's "Expressions" tab.
static NumericLabel() {
// Specify an array of events in which the property should be available.
string[] eventNames = new string[] { "BeforePrint" };
// Specify the property position in the property grid's "Expressions" tab.
// 0 - first, 1000 - last.
int position = 0;
// Specify an array of the property's inner properties.
string[] nestedBindableProperties = null;
// Specify the property's category in the property grid's "Expressions" tab.
// The empty string corresponds to the root category.
string scopeName = "";
// Create and set a description for the "Number" property.
ExpressionBindingDescription description = new ExpressionBindingDescription(
eventNames, position, nestedBindableProperties, scopeName
);
ExpressionBindingDescriptor.SetPropertyDescription(
typeof(NumericLabel), nameof(Number), description
);
}
}
}
using DevExpress.Utils.Serializing;
using DevExpress.XtraReports;
using DevExpress.XtraReports.UI;
using System.ComponentModel;
using DevExpress.XtraReports.Expressions;
using DevExpress.Utils.Design;
namespace WinFormsApp_CustomNumericLabel {
[ToolboxItem(true)]
[DefaultBindableProperty("Number")]
[ToolboxSvgImage("WinFormsApp_CustomNumericLabel.NumericLabel.svg, WinFormsApp_CustomNumericLabel")]
public class NumericLabel : XRLabel {
[DefaultValue(0)]
[XtraSerializableProperty]
public int Number { get; set; }
// Set the "Browsable" and "EditorBrowsable" attributes to "false" and "Never"
// to hide the "Text" property from the "Properties" window and editor (IntelliSense).
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public override string Text {
get { return Number.ToString(); }
set {
int i;
Number = (int.TryParse(value, out i)) ? i : 0;
}
}
// Implement a static constructor as shown below to add
// the "Number" property to the property grid's "Expressions" tab.
static NumericLabel() {
// Specify an array of events in which the property should be available.
string[] eventNames = new string[] { "BeforePrint" };
// Specify the property position in the property grid's "Expressions" tab.
// 0 - first, 1000 - last.
int position = 0;
// Specify an array of the property's inner properties.
string[] nestedBindableProperties = null;
// Specify the property's category in the property grid's "Expressions" tab.
// The empty string corresponds to the root category.
string scopeName = "";
// Create and set a description for the "Number" property.
ExpressionBindingDescription description = new ExpressionBindingDescription(
eventNames, position, nestedBindableProperties, scopeName
);
ExpressionBindingDescriptor.SetPropertyDescription(
typeof(NumericLabel), nameof(Number), description
);
}
}
}
Rebuild the solution. The Number property appears in the Properties window:
You can invoke the Expression Editor to specify an expression:
NumericLabel class inherits the existing XRLabel control class.NumericLabel class implements a new Number property and overrides the Text property.ToolboxItem attribute for the NumericLabel class is set to true to display the custom control in the Toolbox.The DefaultBindableProperty attribute for the Number property is set to true. When you drop a field from the Field List onto the control, the Number property is bound to that field.
A static constructor for the NumericLabel class enables the Number property in the Properties window’s Expressions tab and Expression Editor.
Use the XtraSerializableProperty attribute to serialize custom properties.
The XtraSerializableProperty attribute is responsible for serializing the property in XML. The attribute should be specified to serialize a property that returns a simple type. Complex types require a constructor with the XtraSerializationVisibility argument type (the most commonly used values are Hidden, Collection, Reference, Content).
The DesignerSerializationVisibility attribute is responsible for serializing the CodeDOM in Visual Studio Designer. It has three options - Hidden, Visible, and Content. You should apply Visible to collections or references.
The DefaultValue attribute determines whether the property value is serialized.
Refer to the following help topic for more information: XML Serialization.
To ensure proper serialization of collection properties, apply the XtraSerializableProperty attribute with the XtraSerializationVisibility.Collection parameter, as in the following code snippet:
[XtraSerializableProperty(XtraSerializationVisibility.Collection)]
public List<CustomParameter> CustomParameters { get; set; }
You should implement the IXtraSupportDeserializeCollectionItem interface to define how new elements of the collection are created. All required properties of the CustomParameter class must also be marked with the XtraSerializableProperty attribute.
For more information, review the following article: K18435 - How to serialize a custom property of the DevExpress control’s descendant.