Custom Categories and Functions
As of R1 2019, the RadExpressionEditor control allows users to add custom categories and functions to its UI as well as remove some of the already defined ones.
To do so, you have to create a custom implementation of the ExpressionEditorViewModel and override its virtual methods.
Example 1: The ExpressionEditorViewModel overrides
public class CustomExpressionEditorViewModel : ExpressionEditorViewModel
{
protected override IEnumerable<EditorCategoryModel> GenerateCategories()
{
return base.GenerateCategories();
}
protected override IEnumerable<EditorModelBase> GetFunctionsItemModels()
{
return base.GetFunctionsItemModels();
}
protected override IEnumerable<EditorModelBase> GetFieldsItemModels(object currentItem)
{
return base.GetFieldsItemModels(currentItem);
}
protected override IEnumerable<EditorModelBase> GetOperatorsItemModels()
{
return base.GetOperatorsItemModels();
}
protected override IEnumerable<EditorModelBase> GetConstantsItemModels()
{
return base.GetConstantsItemModels();
}
protected override EditorCategoryModel GetFieldsCategory()
{
return base.GetFieldsCategory();
}
}
Example 2: Set RadExpressionEditor's ViewModel
this.ExpressionEditor.ViewModel = new CustomExpressionEditorViewModel();
Custom Categories
To add custom categories as well as remove certain predefined categories, you need to override the GenerateCategories method.
Example 3: Add custom categories
protected override IEnumerable<EditorCategoryModel> GenerateCategories()
{
List<EditorCategoryModel> list = new List<EditorCategoryModel>(base.GenerateCategories());
EditorCategoryModel favorites = new EditorCategoryModel("Favorites");
EditorCategoryModel math = new EditorCategoryModel("Math");
EditorCategoryModel dateTime = new EditorCategoryModel("DateTime");
math.Children.Add(new FunctionEditorItemModel(typeof(Math).GetMethod("Abs", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(double) }, null), favorites.Name));
math.Children.Add(new FunctionEditorItemModel(typeof(Math).GetMethod("Acos", BindingFlags.Public | BindingFlags.Static), favorites.Name));
math.Children.Add(new FunctionEditorItemModel(typeof(Math).GetMethod("Atan", BindingFlags.Public | BindingFlags.Static), favorites.Name));
math.Children.Add(new FunctionEditorItemModel(typeof(Math).GetMethod("Sqrt", BindingFlags.Public | BindingFlags.Static), favorites.Name));
dateTime.Children.Add(new FunctionEditorItemModel(typeof(DateTime).GetMethod("IsLeapYear", BindingFlags.Public | BindingFlags.Static), favorites.Name));
favorites.Children.Add(math);
favorites.Children.Add(dateTime);
list.Add(favorites);
return list;
}
Figure 1: Custom category
Custom Functions
If you want to add your custom non-static functions to the control you need to set the ExpressionFunctionContext.Context property to an instance of the ExpressionFunctionContext class.
Example 4: Custom ExpressionFunctionContext
public class CustomExpressionFunctionContext : ExpressionFunctionContext
{
[Description("Increase the value by 1")]
public int OnePlus(int input)
{
return ++input;
}
[Description("Increase the value with 2")]
public int TwoPlus(int input)
{
return input + 2;
}
}
Example 5: Set the ExpressionFunctionContext.Context
ExpressionFunctionContext.Context = new CustomExpressionFunctionContext();
Example 6: Add custom functions
protected override IEnumerable<EditorModelBase> GetFunctionsItemModels()
{
List<EditorModelBase> list = new List<EditorModelBase>(base.GetFunctionsItemModels());
var other = list.First(x => x.Name == "Other") as EditorCategoryModel;
other.Children.Insert(5, new FunctionEditorItemModel(typeof(CustomExpressionFunctionContext).GetMethod("OnePlus", BindingFlags.Public | BindingFlags.Instance), other.Name));
other.Children.Add(new FunctionEditorItemModel(typeof(CustomExpressionFunctionContext).GetMethod("TwoPlus", BindingFlags.Public | BindingFlags.Instance), other.Name));
return list;
}
Figure 2: Custom functions
Further Customizations
You can further customize the control by overriding the GetFieldsItemModels, GetOperatorsItemModels, GetConstantsItemModels and GetFieldsCategory methods.
Example 7: Remove operators, constants and fields and add subcategories to the Fields category
protected override IEnumerable<EditorModelBase> GetOperatorsItemModels()
{
List<EditorModelBase> list = new List<EditorModelBase>(base.GetOperatorsItemModels());
list.RemoveAll(m => m.Name.StartsWith("/", System.StringComparison.CurrentCultureIgnoreCase));
list.RemoveAll(m => m.Name.StartsWith("Or", System.StringComparison.CurrentCultureIgnoreCase));
list.RemoveAll(m => m.Name.StartsWith("And", System.StringComparison.CurrentCultureIgnoreCase));
list.RemoveAll(m => m.Name.StartsWith("Not", System.StringComparison.CurrentCultureIgnoreCase));
return list;
}
protected override IEnumerable<EditorModelBase> GetConstantsItemModels()
{
List<EditorModelBase> list = new List<EditorModelBase>(base.GetConstantsItemModels());
list.RemoveAll(m => m.Name.StartsWith("null", System.StringComparison.CurrentCultureIgnoreCase));
return list;
}
protected override IEnumerable<EditorModelBase> GetFieldsItemModels(object currentItem)
{
List<EditorModelBase> list = new List<EditorModelBase>(base.GetFieldsItemModels(currentItem));
list.RemoveAll(m => m.Name.StartsWith("Discontinued", System.StringComparison.CurrentCultureIgnoreCase));
return list;
}
protected override EditorCategoryModel GetFieldsCategory()
{
var fields = base.GetFieldsCategory();
if (fields.Children.Any())
{
var subcategory = new EditorCategoryModel("Subcategory");
subcategory.Children.Add(fields.Children.First(x => x.Name == "Car"));
fields.Children.Add(subcategory);
}
return fields;
}