Hello,
RadPropertyGrid does not properly intersect properties when what is set as SelectedObjects implements the ICustomTypeDescriptor interface. However, the .Net Framework PropertyGrid does not have this problem.
To reproduce the problem, use the attached project.
When setting SelectedObject a ReadOnlyAttribute applies to the grid. But when wrapping it in an object[] and assign it to SelectedObjects the grid allows editing.
Sample application included.
Currently, the only possible way to set the value to null is to select the whole text and press the Delete key.
If the value is cleared by the backspace key, it is restored when the control loses focus.
If the value is cleared by multiple times clicking the delete key and the cursor is in the first position, the previous value is restored when the control loses focus.
Workaround:
Subscribe to the TextChanged event of the spin editor and explicitly set the NullableValue of the BaseSpinEditorElement:
this.radPropertyGrid1.EditorInitialized += this.RadPropertyGrid1_EditorInitialized;
private void RadPropertyGrid1_EditorInitialized(object sender, PropertyGridItemEditorInitializedEventArgs e)
{
if (e.Editor is PropertyGridSpinEditor spinEdit)
{
if (spinEdit.EditorElement is BaseSpinEditorElement editorElement && editorElement.EnableNullValueInput)
{
editorElement.TextChanged -= this.EditorElement_TextChanged;
editorElement.TextChanged += this.EditorElement_TextChanged;
}
}
}
private void EditorElement_TextChanged(object sender, EventArgs e)
{
if (sender is BaseSpinEditorElement editorElement && string.IsNullOrWhiteSpace(editorElement.Text))
{
editorElement.NullableValue = null;
}
}
Workaround: Private Sub RadPropertyGrid1_EditorRequired(sender As Object, e As PropertyGridEditorRequiredEventArgs) Handles RadPropertyGrid1.EditorRequired Dim te As PropertyGridTableElement = TryCast(sender, PropertyGridTableElement) If e.EditorType = GetType(PropertyGridSpinEditor) Then Dim editor As New CustomPropertyGridSpinEditor If editor IsNot Nothing AndAlso te IsNot Nothing Then Dim type As Type = RadPropertyGrid1.SelectedObject.[GetType]().GetProperty(e.Item.Name).PropertyType If type = GetType(System.Double) Then DirectCast(editor.EditorElement, BaseSpinEditorElement).DecimalPlaces = 4 e.Editor = editor End If End If End If End Sub Public Class CustomPropertyGridSpinEditor Inherits PropertyGridSpinEditor Public Overrides Sub Initialize(owner As Object, value As Object) Dim decimalPlaces As Integer = Me.DecimalPlaces MyBase.Initialize(owner, value) Dim element As PropertyGridItemElement = TryCast(owner, PropertyGridItemElement) Dim item As PropertyGridItem = TryCast(element.Data, PropertyGridItem) Dim editedType As Type = item.PropertyType If ((editedType = GetType(Decimal) OrElse editedType = GetType(Double) OrElse editedType = GetType(Single)) AndAlso decimalPlaces <> 0) Then DirectCast(Me.EditorElement, BaseSpinEditorElement).DecimalPlaces = decimalPlaces Me.Value = value End If End Sub End Class
To reproduce: run the attached sample project and follow the steps from the gif file. Workaround: cancel the edit operation when handling the MouseDown event of RadPropertyGrid: private void radPropertyGrid1_MouseDown(object sender, MouseEventArgs e) { var elementUnderMouse = this.radPropertyGrid1.ElementTree.GetElementAtPoint(e.Location).FindAncestor<RadScrollBarElement>(); if (elementUnderMouse!=null) { this.radPropertyGrid1.CancelEdit(); } }
Use the editor from the following article to reproduce: https://docs.telerik.com/devtools/winforms/propertygrid/editors/using-custom-editor Workaround: void TrackBarEditor_ValueChanged(object sender, EventArgs e) { PropertyGridItemElement owner = this.OwnerElement as PropertyGridItemElement; if (owner != null) { var method = owner.PropertyTableElement.GetType().GetMethod("OnValueChanged", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); method.Invoke(owner.PropertyTableElement, new object[] { this, EventArgs.Empty }); } }
When you have a property that is bool? or ToggleState, it would be good to have three-state functionality for the PropertyGridCheckBoxItemElement.
To reproduce: Public Class RadForm1 Sub New() InitializeComponent() RadPropertyGrid1.SelectedObject = New MyProperties End Sub Public Class MyProperties Private _height As Integer = 70 <Browsable(True)> <Category("Rows")> <DisplayName("Height")> _ <Description("Sets the height of the row. Range 70 to 200.")> _ <RadRange(70, 200)> _ Public Property Height() As Integer Get Return _height End Get Set(ByVal Value As Integer) _height = Value End Set End Property End Class End Class When you activate the editor you will notice that you are allowed to enter values outside the specified range 7-200. Workaround: AddHandler Me.RadPropertyGrid1.EditorInitialized, AddressOf PropertyGridEditorInitialized Private Sub PropertyGridEditorInitialized(sender As Object, e As PropertyGridItemEditorInitializedEventArgs) Dim spinEditor As PropertyGridSpinEditor = TryCast(e.Editor, PropertyGridSpinEditor) If spinEditor IsNot Nothing Then spinEditor.MinValue = 70 spinEditor.MaxValue = 200 End If End Sub
Use attached to reproduce. Workaround radPropertyGrid1.ItemSpacing = 1;
To reproduce: this.radPropertyGrid1.SelectedObject = this; this.radPropertyGrid1.PropertyGridElement.SplitElement.HelpElement.MinSize = new Size(0, 60); Please refer to the attached gif file. Workaround: this.radPropertyGrid1.SelectedObject = this; this.radPropertyGrid1.PropertyGridElement.SplitElement.HelpElement.MinSize = new Size(0, 60); this.radPropertyGrid1.PropertyGridElement.SplitElement.HelpElement.HelpTitleElement.MinSize = new Size(0,20); this.radPropertyGrid1.PropertyGridElement.SplitElement.HelpElement.HelpTitleElement.PropertyChanged += HelpTitleElement_PropertyChanged; private void HelpTitleElement_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Bounds") { if (this.radPropertyGrid1.PropertyGridElement.SplitElement.HelpElement.HelpContentElement.Location.Y != 20) { this.radPropertyGrid1.PropertyGridElement.SplitElement.HelpElement.HelpContentElement.Location = new Point(0, 20); } } } Note: the description element may be floating but it doesn't overlap the title.
How to reproduce: associate the control with an object having a Font property. It can be the form itself, then try and change the font-size, e.g: -1. The standard property grid displays a message box with the error. Workaround handle the RadPropertyGrid.EditorInitialized event: private void RadPropertyGrid_EditorInitialized(object sender, PropertyGridItemEditorInitializedEventArgs e) { PropertyGridSpinEditor editor = e.Editor as PropertyGridSpinEditor; if (editor != null && e.Item.Parent != null && e.Item.Parent.Name == "Font" && e.Item.Name == "Size") { editor.MinValue = 1; } }
To reproduce: use the following code snippet and follow the steps from the gif file: PropertyStoreItem item1 = new PropertyStoreItem(typeof(string), "Test1", "Test1"); PropertyStoreItem item2 = new PropertyStoreItem(typeof(string), "Test2", "Test2"); RadPropertyStore store = new RadPropertyStore(); store.Add(item1); store.Add(item2); this.radPropertyGrid1.SelectedObject = store; this.radPropertyGrid1.ToolbarVisible = true; Workaround: close the editor programmatically when the search box gets focus. this.radPropertyGrid1.PropertyGridElement.ToolbarElement.SearchTextBoxElement.TextBoxItem.GotFocus += TextBoxItem_GotFocus; private void TextBoxItem_GotFocus(object sender, EventArgs e) { this.radPropertyGrid1.EndEdit(); }
Please refer to the attached video illustrating the incorrect behavior of the context menu. Workaround: public RadForm1() { InitializeComponent(); this.radPropertyGrid1.SelectedObject = this; this.radPropertyGrid1.ToolbarVisible = true; this.radPropertyGrid1.RadContextMenu = new CustomPropertyGridDefaultContextMenu(this.radPropertyGrid1.PropertyGridElement.PropertyTableElement); } public class CustomPropertyGridDefaultContextMenu : Telerik.WinControls.UI.PropertyGridDefaultContextMenu { PropertyGridTableElement tableElement; public CustomPropertyGridDefaultContextMenu(PropertyGridTableElement propertyGridElement) : base(propertyGridElement) { tableElement = propertyGridElement; } protected override void OnDropDownOpening(CancelEventArgs args) { base.OnDropDownOpening(args); PropertyGridItemBase item = this.tableElement.SelectedGridItem; if (item != null) { if (!(item is PropertyGridGroupItem)) { this.EditMenuItem.Visibility = ElementVisibility.Visible; this.ResetMenuItem.Visibility = ElementVisibility.Visible; } } } }
How to reproduce: check the attached screenshot Workaround: use the attached custom theme
To reproduce: - Add RadPropertyGrid to a form and set the theme to MaterialTeal. The issue is observed in the ThemeViewer as well. Workaround: radPropertyGrid1.PropertyGridElement.ToolbarElement.AlphabeticalToggleButton.TextWrap = true; radPropertyGrid1.PropertyGridElement.ToolbarElement.CategorizedToggleButton.TextWrap = true; //or radPropertyGrid1.PropertyGridElement.ToolbarElementHeight = 68;
RadSpinEditor now supports null values. This functionality is relevant for the PropertyGridSpinEditor as well http://docs.telerik.com/devtools/winforms/editors/spineditor/null-value-support