Editor Attribute

RadPropertyGrid provides support for the Telerik attribute EditorAttribute that enables the user to define an editor for each property directly in its definition.

EditorAttribute is placed in Telerik.Windows.Controls.Data binary in Telerik.Windows.Controls.Data.PropertyGrid namespace. You need to have a reference to the assembly and add a using for the namespace. You can check the Getting Started with RadPropertyGrid article for more basic information.

It has three properties:

  • EditorType: Specifies the type of the editor used for the property.

  • TargetProperty: Defines the property of the custom editor that will be used for the binding.

  • EditorStyle: Sets the style of the UI component used for hosting the custom editor. Its values can be:

    • DropDown: A dropdown button which content is the custom editor to be displayed.

    • Modal: A button that shows a modal dialog window with the custom editor inside.

    • None (default value): The editor will be placed directly in PropertyGridField and no special UI element will be used.

Constructors

Consequently, EditorAttribute has various constructors that can be used depending on the necessities. Their main difference is that either the Type of the editor is passed as parameter, or the string representation of the editor's Type.

  • public EditorAttribute(Type editorType)

  • public EditorAttribute(Type editorType, EditorStyle editorStyle)

  • public EditorAttribute(Type editorType, string targetProperty)

  • public EditorAttribute(Type editorType, string targetProperty, EditorStyle editorStyle)

  • public EditorAttribute(string editorTypeName, string assemblyFile)

  • public EditorAttribute(string editorTypeName, string assemblyFile, EditorStyle editorStyle)

  • public EditorAttribute(string editorTypeName, string assemblyFile, string targetProperty)

  • public EditorAttribute(string editorTypeName, string assemblyFile, string targetProperty, EditorStyle editorStyle)

The assemblyFile parameter represents the absolute file path of the needed assembly

For the purposes of this example, the definition of RadPropertyGrid is:

Example 1: Defining RadPropertyGrid

<telerik:RadPropertyGrid x:Name="propertyGrid" Item="{Binding Captain}" /> 

The property Captain is defined in the ViewModel as follows:

Example 2: Defining property in the ViewModel

private Player captain; 
public Player Captain 
{ 
    get 
    { 
        if (this.captain == null) 
        { 
            this.captain = new Player("Pepe Reina", 25, Position.GK, "Spain") { PhoneNumber = new PhoneNumber() { CountryCode = "359", RegionCode = "885", Number = "434343" } }; 
        } 
        return this.captain; 
    } 
} 
Private _captain As Player 
Public ReadOnly Property Captain() As Player 
    Get 
        If Me._captain Is Nothing Then 
            Me._captain = New Player("Pepe Reina", 25, Position.GK, "Spain") With { 
                .PhoneNumber = New PhoneNumber() With { 
                    .CountryCode = "359", 
                    .RegionCode = "885", 
                    .Number = "434343" 
                } 
            } 
        End If 
        Return Me._captain 
    End Get 
End Property 

The definitions of the Custom editor PhoneEditorControl, the Player business object used and the full implementation of the PhoneNumber class can be found in the Define Data section.

  • EditorAttribute(Type editorType) – only the type of the editor can be specified:

Example 3: Specifying the type of the editor

private PhoneNumber phoneNumber; 
[Telerik.Windows.Controls.Data.PropertyGrid.Editor(typeof(PhoneEditorControl))] 
public PhoneNumber PhoneNumber 
{ 
    get 
    { 
        return this.phoneNumber; 
    } 
    set 
    { 
        if (this.phoneNumber != value) 
        { 
            this.phoneNumber = value; 
            this.OnPropertyChanged("PhoneNumber"); 
        } 
    } 
} 
Private _phoneNumber As PhoneNumber 
<Telerik.Windows.Controls.Data.PropertyGrid.Editor(GetType(PhoneEditorControl))> 
Public Property PhoneNumber() As PhoneNumber 
    Get 
        Return Me._phoneNumber 
    End Get 
    Set(ByVal value As PhoneNumber) 
        If Me._phoneNumber IsNot value Then 
            Me._phoneNumber = value 
            Me.OnPropertyChanged("PhoneNumber") 
        End If 
    End Set 
End Property 
  • EditorAttribute(string editorTypeName, string assemblyFile) – the string representation of the editor's type and the absolute file path of the assembly can be specified:

Example 4: Specifying the type of the editor as string and passing the absolute file path of the assembly

private PhoneNumber phoneNumber; 
[Telerik.Windows.Controls.Data.PropertyGrid.Editor("EditorAttribute.PhoneEditorControl", @"....\bin\Debug\PhoneEditor.dll")] 
public PhoneNumber PhoneNumber 
{ 
    get 
    { 
        return this.phoneNumber; 
    } 
    set 
    { 
        if (this.phoneNumber != value) 
        { 
            this.phoneNumber = value; 
            this.OnPropertyChanged("PhoneNumber"); 
        } 
    } 
} 
Private _phoneNumber As PhoneNumber 
<Telerik.Windows.Controls.Data.PropertyGrid.Editor("EditorAttribute.PhoneEditorControl", "....\bin\Debug\PhoneEditor.dll")> _ 
Public Property PhoneNumber() As PhoneNumber 
    Get 
        Return Me._phoneNumber 
    End Get 
    Set(value As PhoneNumber) 
        If Not Me._phoneNumber Is value Then 
            Me._phoneNumber = value 
            Me.OnPropertyChanged("PhoneNumber") 
        End If 
    End Set 
End Property 

It will look like:

Figure 1: EditorAtrribute with editorType specified

Rad Property Grid Custom Editor

  • EditorAttribute(Type editorType, EditorStyle editorStyle) – the type of the editor and the style of the containing host:

Example 5: Specifying the type of the editor and the style of the containing host

private PhoneNumber phoneNumber; 
[Telerik.Windows.Controls.Data.PropertyGrid.Editor(typeof(PhoneEditorControl), Telerik.Windows.Controls.Data.PropertyGrid.EditorStyle.DropDown)] 
public PhoneNumber PhoneNumber 
{ 
    get 
    { 
        return this.phoneNumber; 
    } 
    set 
    { 
        if (this.phoneNumber != value) 
        { 
            this.phoneNumber = value; 
            this.OnPropertyChanged("PhoneNumber"); 
        } 
    } 
} 
Private _phoneNumber As PhoneNumber 
<Telerik.Windows.Controls.Data.PropertyGrid.Editor(GetType(PhoneEditorControl), EditorStyle.DropDown)> 
Public Property PhoneNumber() As PhoneNumber 
    Get 
        Return Me._phoneNumber 
    End Get 
    Set(ByVal value As PhoneNumber) 
        If Me._phoneNumber IsNot value Then 
            Me._phoneNumber = value 
            Me.OnPropertyChanged("PhoneNumber") 
        End If 
    End Set 
End Property 
  • EditorAttribute(string editorTypeName, string assemblyFile, EditorStyle editorStyle) - the style of the containing host can be specified:

Example 6: Specifying the type of the editor and the absolute file path of the assembly as string, as well the style of the containing host

private PhoneNumber phoneNumber; 
[Telerik.Windows.Controls.Data.PropertyGrid.Editor("EditorAttribute.PhoneEditorControl", @"....\bin\Debug\PhoneEditor.dll", 
Telerik.Windows.Controls.Data.PropertyGrid.EditorStyle.Modal)] 
public PhoneNumber PhoneNumber 
{ 
    get 
    { 
        return this.phoneNumber; 
    } 
    set 
    { 
        if (this.phoneNumber != value) 
        { 
            this.phoneNumber = value; 
            this.OnPropertyChanged("PhoneNumber"); 
        } 
    } 
} 
Private _phoneNumber As PhoneNumber 
<Telerik.Windows.Controls.Data.PropertyGrid.Editor("EditorAttribute.PhoneEditorControl", 
    "....\bin\Debug\PhoneEditor.dll", Telerik.Windows.Controls.Data.PropertyGrid.EditorStyle.Modal)> _ 
Public Property PhoneNumber() As PhoneNumber 
    Get 
        Return Me._phoneNumber 
    End Get 
    Set(value As PhoneNumber) 
        If Not Me._phoneNumber Is value Then 
            Me._phoneNumber = value 
            Me.OnPropertyChanged("PhoneNumber") 
        End If 
    End Set 
End Property 

In this case PhoneEditorControl will be defined in a DropDownEditor control and it will look like:

Figure 2: EditorAtrribute with editorType and editorStyle specified

Rad Property Grid Custom Editor In Drop Down

  • EditorAttribute(Type editorType, string targetProperty) – the type of the editor and its property that you want to bind to. For instance:

Example 7: Specifying the type of the editor and the target property

private int number; 
[Telerik.Windows.Controls.Data.PropertyGrid.Editor(typeof(RadNumericUpDown), "Value")] 
public int Number 
{ 
    get { return this.number; } 
    set 
    { 
        if (value != this.number) 
        { 
            this.number = value; 
            this.OnPropertyChanged("Number"); 
        } 
    } 
} 
Private _number As Integer 
<Telerik.Windows.Controls.Data.PropertyGrid.Editor(GetType(RadNumericUpDown), "Value")> 
Public Property Number() As Integer 
    Get 
        Return Me._number 
    End Get 
    Set(ByVal value As Integer) 
        If value <> Me._number Then 
            Me._number = value 
            Me.OnPropertyChanged("Number") 
        End If 
    End Set 
End Property 
  • EditorAttribute(string editorTypeName, string assemblyFile, string targetProperty) - the target property can be specified:

Example 8: Specifying the type of the editor and the absolute file path of the assembly as string, as well the target property

private int number; 
[Telerik.Windows.Controls.Data.PropertyGrid.Editor("Telerik.Windows.Controls.RadNumericUpDown" 
    , @"....\bin\Debug\Telerik.Windows.Controls.Input.dll", "Value")] 
public int Number 
{ 
    get { return this.number; } 
    set 
    { 
        if (value != this.number) 
        { 
            this.number = value; 
            this.OnPropertyChanged("Number"); 
        } 
    } 
} 
Private _number As Integer 
<Telerik.Windows.Controls.Data.PropertyGrid.Editor("Telerik.Windows.Controls.RadNumericUpDown", 
    "....\bin\Debug\Telerik.Windows.Controls.Input.dll", "Value")> _ 
Public Property Number() As Integer 
    Get 
        Return Me._number 
    End Get 
    Set(value As Integer) 
        If value <> Me._number Then 
            Me._number = value 
            Me.OnPropertyChanged("Number") 
        End If 
    End Set 
End Property 

In this case the property from your business object – Number – will be bound to the ValueProperty of RadNumericUpDown control.

The result will be:

Figure 3: EditorAtrribute with editorType and targetProperty specified

Rad Property Grid Target Property

  • EditorAttribute(Type editorType, string targetProperty, EditorStyle editorStyle) – with this constructor all properties are set – the type of the editor, its property that will be used for the binding and the type of the host it will be placed inside. For example:

Example 9: Specifying the type of the editor, the target property and style of the containing host

private string name; 
[Telerik.Windows.Controls.Data.PropertyGrid.Editor(typeof(TextBox), "Text", EditorStyle.Modal)] 
public string Name 
{ 
    get { return this.name; } 
    set 
    { 
        if (value != this.name) 
        { 
            this.name = value; 
            this.OnPropertyChanged("Name"); 
        } 
    } 
} 
Private _name As String 
<Telerik.Windows.Controls.Data.PropertyGrid.Editor(GetType(TextBox), "Text", EditorStyle.Modal)> 
Public Property Name() As String 
    Get 
        Return Me._name 
    End Get 
    Set(ByVal value As String) 
        If value <> Me._name Then 
            Me._name = value 
            Me.OnPropertyChanged("Name") 
        End If 
    End Set 
End Property 
  • EditorAttribute(string editorTypeName, string assemblyFile, string targetProperty, EditorStyle editorStyle) - specifying both the target property

Example 10: Specifying the type of the editor and the absolute file path of the assembly as string, the target property and the style for the containing host

private string name; 
[Telerik.Windows.Controls.Data.PropertyGrid.Editor("System.Windows.Controls.TextBox", 
gram Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\Profile\Client\PresentationFramework.dll", 
    "Text", Telerik.Windows.Controls.Data.PropertyGrid.EditorStyle.Modal)] 
public string Name 
{ 
    get { return this.name; } 
    set 
    { 
        if (value != this.name) 
        { 
            this.name = value; 
            this.OnPropertyChanged("Name"); 
        } 
    } 
} 
Private _name As String 
<Telerik.Windows.Controls.Data.PropertyGrid.Editor("System.Windows.Controls.TextBox", 
    "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.0\Profile\Client\PresentationFramework.dll", "Text", 
    Telerik.Windows.Controls.Data.PropertyGrid.EditorStyle.Modal)> _ 
Public Property Name() As String 
    Get 
        Return Me._name 
    End Get 
    Set(value As String) 
        If value <> Me._name Then 
            Me._name = value 
            Me.OnPropertyChanged("Name") 
        End If 
    End Set 
End Property 

It will look like:

Figure 4: EditorAtrribute with editorType, targetProperty and editorStyle specified

Rad Property Grid Custom Editor In Modal

Define Data

The definition of the Custom editor PhoneEditorControl is:

Example 11: Defining the custom editor

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
      mc:Ignorable="d" > 
    <UserControl.Resources> 
        <Style TargetType="TextBox"> 
            <Setter Property="BorderBrush" Value="Transparent" /> 
        </Style> 
    </UserControl.Resources> 
 
    <StackPanel Orientation="Horizontal" Height="20"> 
        <TextBlock Text="+" /> 
        <TextBox Text="{Binding CountryCode, Mode=TwoWay}" /> 
        <TextBlock Text=" (" /> 
        <TextBox Text="{Binding RegionCode, Mode=TwoWay}" /> 
        <TextBlock Text=") " /> 
        <TextBox Text="{Binding Number, Mode=TwoWay}" /> 
    </StackPanel> 
 
</UserControl> 

The definition of the PhoneNumber class is:

Example 12: Defining PhoneNumber object

public class PhoneNumber : INotifyPropertyChanged 
{ 
    private string countryCode; 
    public string CountryCode 
    { 
        get 
        { 
            return this.countryCode; 
        } 
        set 
        { 
            if (this.countryCode != value) 
            { 
                this.countryCode = value; 
                this.OnPropertyChanged("CountryCode"); 
            } 
        } 
    } 
 
    private string number; 
    public string Number 
    { 
        get 
        { 
            return this.number; 
        } 
        set 
        { 
            if (this.number != value) 
            { 
                this.number = value; 
                this.OnPropertyChanged("Number"); 
            } 
        } 
    } 
 
    private string regionCode; 
    public string RegionCode 
    { 
        get 
        { 
            return this.regionCode; 
        } 
        set 
        { 
            if (this.regionCode != value) 
            { 
                this.regionCode = value; 
                this.OnPropertyChanged("RegionCode"); 
            } 
        } 
    } 
 
    public event PropertyChangedEventHandler PropertyChanged; 
 
    private void OnPropertyChanged(string propertyName) 
    { 
        if (this.PropertyChanged != null) 
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
Public Class PhoneNumber 
    Implements INotifyPropertyChanged 
 
    Private _countryCode As String 
    Public Property CountryCode() As String 
        Get 
            Return Me._countryCode 
        End Get 
        Set(ByVal value As String) 
            If Me._countryCode <> value Then 
                Me._countryCode = value 
                Me.OnPropertyChanged("CountryCode") 
            End If 
        End Set 
    End Property 
 
    Private _number As String 
    Public Property Number() As String 
        Get 
            Return Me._number 
        End Get 
        Set(ByVal value As String) 
            If Me._number <> value Then 
                Me._number = value 
                Me.OnPropertyChanged("Number") 
            End If 
        End Set 
    End Property 
 
    Private _regionCode As String 
    Public Property RegionCode() As String 
        Get 
            Return Me._regionCode 
        End Get 
        Set(ByVal value As String) 
            If Me._regionCode <> value Then 
                Me._regionCode = value 
                Me.OnPropertyChanged("RegionCode") 
            End If 
        End Set 
    End Property 
 
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 
 
    Private Sub OnPropertyChanged(ByVal propertyName As String) 
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) 
    End Sub 
End Class 

The definition of the Player business object used for the example is:

Example 13: Defining Player object

public class Player : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
 
    private string name; 
    private int number; 
    private Position position; 
    private string country; 
    private PhoneNumber phoneNumber; 
 
    [Telerik.Windows.Controls.Data.PropertyGrid.Editor(typeof(TextBox), "Text", EditorStyle.Modal)] 
    public string Name 
    { 
        get { return this.name; } 
        set 
        { 
            if (value != this.name) 
            { 
                this.name = value; 
                this.OnPropertyChanged("Name"); 
            } 
        } 
    } 
 
    [Telerik.Windows.Controls.Data.PropertyGrid.Editor(typeof(RadNumericUpDown), "Value")] 
    public int Number 
    { 
        get { return this.number; } 
        set 
        { 
            if (value != this.number) 
            { 
                this.number = value; 
                this.OnPropertyChanged("Number"); 
            } 
        } 
    } 
 
    public Position Position 
    { 
        get { return this.position; } 
        set 
        { 
            if (value != this.position) 
            { 
                this.position = value; 
                this.OnPropertyChanged("Position"); 
            } 
        } 
    } 
 
    [Telerik.Windows.Controls.Data.PropertyGrid.Editor(typeof(PhoneEditorControl), Telerik.Windows.Controls.Data.PropertyGrid.EditorStyle.DropDown)] 
    public PhoneNumber PhoneNumber 
    { 
        get 
        { 
            return this.phoneNumber; 
        } 
        set 
        { 
            if (this.phoneNumber != value) 
            { 
                this.phoneNumber = value; 
                this.OnPropertyChanged("PhoneNumber"); 
            } 
        } 
    } 
 
    public string Country 
    { 
        get { return this.country; } 
        set 
        { 
            if (value != this.country) 
            { 
                this.country = value; 
                this.OnPropertyChanged("Country"); 
            } 
        } 
    } 
 
    public Player() 
    { 
 
    } 
 
    public Player(string name, int number, Position position, string country) 
    { 
        this.name = name; 
        this.number = number; 
        this.position = position; 
        this.country = country; 
    } 
 
    protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) 
    { 
        PropertyChangedEventHandler handler = this.PropertyChanged; 
        if (handler != null) 
        { 
            handler(this, args); 
        } 
    } 
 
    private void OnPropertyChanged(string propertyName) 
    { 
        this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); 
    } 
} 
Public Class Player 
    Implements INotifyPropertyChanged 
 
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 
 
    Private _name As String 
    Private _number As Integer 
    Private _position As Position 
    Private _country As String 
    Private _phoneNumber As PhoneNumber 
 
    <Telerik.Windows.Controls.Data.PropertyGrid.Editor(GetType(TextBox), "Text", EditorStyle.Modal)> 
    Public Property Name() As String 
        Get 
            Return Me._name 
        End Get 
        Set(ByVal value As String) 
            If value <> Me._name Then 
                Me._name = value 
                Me.OnPropertyChanged("Name") 
            End If 
        End Set 
    End Property 
 
    <Telerik.Windows.Controls.Data.PropertyGrid.Editor(GetType(RadNumericUpDown), "Value")> 
    Public Property Number() As Integer 
        Get 
            Return Me._number 
        End Get 
        Set(ByVal value As Integer) 
            If value <> Me._number Then 
                Me._number = value 
                Me.OnPropertyChanged("Number") 
            End If 
        End Set 
    End Property 
 
    Public Property Position() As Position 
        Get 
            Return Me._position 
        End Get 
        Set(ByVal value As Position) 
            If value <> Me._position Then 
                Me._position = value 
                Me.OnPropertyChanged("Position") 
            End If 
        End Set 
    End Property 
 
    <Telerik.Windows.Controls.Data.PropertyGrid.Editor(GetType(PhoneEditorControl), EditorStyle.DropDown)> 
    Public Property PhoneNumber() As PhoneNumber 
        Get 
            Return Me._phoneNumber 
        End Get 
        Set(ByVal value As PhoneNumber) 
            If Me._phoneNumber IsNot value Then 
                Me._phoneNumber = value 
                Me.OnPropertyChanged("PhoneNumber") 
            End If 
        End Set 
    End Property 
 
    Public Property Country() As String 
        Get 
            Return Me._country 
        End Get 
        Set(ByVal value As String) 
            If value <> Me._country Then 
                Me._country = value 
                Me.OnPropertyChanged("Country") 
            End If 
        End Set 
    End Property 
 
    Public Sub New() 
 
    End Sub 
 
    Public Sub New(ByVal name As String, ByVal number As Integer, ByVal position As Position, ByVal country As String) 
        Me._name = name 
        Me._number = number 
        Me._position = position 
        Me._country = country 
    End Sub 
 
    Protected Overridable Sub OnPropertyChanged(ByVal args As PropertyChangedEventArgs) 
        Dim handler As PropertyChangedEventHandler = Me.PropertyChangedEvent 
        If handler IsNot Nothing Then 
            handler(Me, args) 
        End If 
    End Sub 
 
    Private Sub OnPropertyChanged(ByVal propertyName As String) 
        Me.OnPropertyChanged(New PropertyChangedEventArgs(propertyName)) 
    End Sub 
End Class 

Position the Modal Editor

As of the 2019.2.722 latest internal build, you can control the position of the modal window when using the Modal EditorStyle via the new WindowStartupLocation, WindowTop and WindowLeft properties of the ModalEditor control.

The WindowStartupLocation property must be set to Manual for the WindowTop and WindowLeft values to have any effect.

These properties can be set either through a style targeting the ModalEditor control or by handling the FieldLoaded event in code-behind.

Example 14: Positioning the ModalEditor through a style for the ModalEditor

<Style TargetType="telerik:ModalEditor"> 
    <Setter Property="WindowStartupLocation" Value="Manual"/> 
    <Setter Property="WindowTop" Value="500"/> 
    <Setter Property="WindowLeft" Value="250"/> 
</Style> 

Example 15: Positioning the ModalEditor in the FieldLoaded event

private void PropertyGrid_FieldLoaded(object sender, Telerik.Windows.Controls.Data.PropertyGrid.FieldEventArgs e) 
{ 
    var modalEditor = e.Field.Content as ModalEditor; 
 
    if (modalEditor != null) 
    { 
        modalEditor.WindowStartupLocation = WindowStartupLocation.Manual; 
        modalEditor.WindowTop = 500; 
        modalEditor.WindowLeft = 250; 
    } 
} 
Private Sub PropertyGrid_FieldLoaded(ByVal sender As Object, ByVal e As Telerik.Windows.Controls.Data.PropertyGrid.FieldEventArgs) 
    Dim modalEditor = TryCast(e.Field.Content, ModalEditor) 
 
    If modalEditor IsNot Nothing Then 
        modalEditor.WindowStartupLocation = WindowStartupLocation.Manual 
        modalEditor.WindowTop = 500 
        modalEditor.WindowLeft = 250 
    End If 
End Sub 

See Also

In this article