This would be really useful functionality. We often need to implement this as we have many domain classes with Lists of doubles / ints.
Following Ticket 1657199 here is one way to acheive this functionality.
It will provide a value type Add command for all collections which inherit from IList.
In your code behind call:
this.radPropertyGrid.AutoGeneratingPropertyDefinition += ValueTypeAddCommandProvider.AutoGeneratePropertyDefinition;
And add this to your codebase:
using System;
using System.Collections;
using System.Windows;
using System.Windows.Markup;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Data.CollectionNavigator;
using Telerik.Windows.Controls.Data.PropertyGrid;
namespace _1657199;
public class ValueTypeAddCommandProvider : CollectionNavigatorBaseCommandProvider {
public ValueTypeAddCommandProvider() : base(null) { }
public ValueTypeAddCommandProvider(CollectionNavigatorBase collectionEditor) : base(collectionEditor) {
this.CollectionNavigator = collectionEditor;
}
public override void AddNew() {
if (CollectionNavigator.Source is IList list) {
var t = this.CollectionNavigator.Source.GetType();
if (t.IsGenericType && t.GenericTypeArguments.Length == 1 && t.GenericTypeArguments[0].IsValueType) {
var listType = t.GenericTypeArguments[0];
var newItem = Activator.CreateInstance(listType);
if (newItem != null) {
list.Add(newItem);
}
}
}
}
public override bool CanAddNewExecute() => true;
public static void AutoGeneratePropertyDefinition(object sender, AutoGeneratingPropertyDefinitionEventArgs e)
{
var descriptor = e.PropertyDefinition.PropertyDescriptor;
var isPrimitiveList = descriptor is { PropertyType: { IsGenericType: true, GenericTypeArguments.Length: 1 } } &&
descriptor.PropertyType.IsAssignableTo(typeof(IList)) &&
descriptor.PropertyType.GenericTypeArguments[0].IsValueType;
if (isPrimitiveList) {
Type editorType = typeof(CollectionEditorPicker);
Type commandType = typeof(ValueTypeAddCommandProvider);
var parserContext = new ParserContext();
parserContext.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
parserContext.XmlnsDictionary.Add("myTelerik", $"clr-namespace:{editorType.Namespace};assembly={editorType.Assembly.GetName().Name}");
parserContext.XmlnsDictionary.Add("myCommand", $"clr-namespace:{commandType.Namespace};assembly={commandType.Assembly.GetName().Name}");
e.PropertyDefinition.EditorTemplate = XamlReader.Parse("<DataTemplate>" +
$" <myTelerik:{nameof(CollectionEditorPicker)} {nameof(CollectionEditorPicker.Source)}=\"{{Binding Path={descriptor.Name}}}\"> " +
$"<myTelerik:{nameof(CollectionEditorPicker)}.{nameof(CollectionEditorPicker.CommandProvider)}>" +
$"<myCommand:{nameof(ValueTypeAddCommandProvider)}/>" +
$"</myTelerik:{nameof(CollectionEditorPicker)}.{nameof(CollectionEditorPicker.CommandProvider)}>" +
$"</myTelerik:{nameof(CollectionEditorPicker)}>" +
"</DataTemplate>", parserContext) as DataTemplate;
}
}
}