Hello,
I cannot get a C# enumeration property based on dynamically created DefineEnum call to show up as popup on a PropertyGrid. I've tried several things but nothing worked. Also, I am dynamically creating the PropertyDefinition items instead of statically defining anything via XAML.
Here is the basic code to load the property definitions:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
PropertyDefinitionCollection properties = EditorPropertyGrid.PropertyDefinitions;
List<
KeyValueBase
> testList = new List<
KeyValueBase
>();
TestEnumKeyValue first = new TestEnumKeyValue() { Key = "Static Enum Prop", Value = TestEnum.test3 };
testList.Add(first);
properties.Add(new PropertyDefinition()
{
DisplayName = first.Key,
Binding = new Binding("Value") { Source = first }
});
DynamicEnumBuilder _enums = new DynamicEnumBuilder();
_enums.BuildDictionaries();
Type dynamicEnum = _enums.getEnum("Employee", "Status");
EnumKeyValue second = new EnumKeyValue() { Key = "Dynamic Enum Prop", Value = Enum.Parse(dynamicEnum, "PartTime")};
testList.Add(second);
properties.Add(new PropertyDefinition()
{
DisplayName = second.Key,
Binding = new Binding("Value") { Source = second }
});
// ************************
EditorPropertyGrid.Item = testList;
}
Here are the key value pair definitions:
enum TestEnum
{
test1,
test2,
test3
}
class KeyValueBase
{
}
class TestEnumKeyValue : KeyValueBase
{
public string Key { get; set; }
public TestEnum Value { get; set; }
}
class EnumKeyValue : KeyValueBase
{
public string Key { get; set; }
public object Value { get; set; }
}
Here is the XAML:
<
Grid
x:Name
=
"EditorGrid"
>
<
telerik:RadPropertyGrid
x:Name
=
"EditorPropertyGrid"
Margin
=
"10,10,10,10"
DescriptionPanelVisibility
=
"Collapsed"
SearchBoxVisibility
=
"Collapsed"
AutoGeneratePropertyDefinitions
=
"False"
NestedPropertiesVisibility
=
"Visible"
AutoGenerateBindingPaths
=
"False"
SortAndGroupButtonsVisibility
=
"Collapsed"
/>
</
Grid
>
And here is how I generate the dynamic enum:
class DynamicEnumBuilder
{
public Dictionary<
string
, Dictionary<string, Type>> _enumDictionary = new Dictionary<
string
, Dictionary<string, Type>>();
public void BuildDictionaries()
{
Dictionary<
string
, Dictionary<string, List<ValuePair>>> _rawDictionary = new Dictionary<
string
, Dictionary<string, List<ValuePair>>>();
_rawDictionary["Employee"] = new Dictionary<
string
, List<ValuePair>>();
_rawDictionary["Employee"]["Status"] = new List<
ValuePair
>();
_rawDictionary["Employee"]["Status"].Add(new ValuePair() { Name = "FullTime", StoredValue = "1" });
_rawDictionary["Employee"]["Status"].Add(new ValuePair() { Name = "PartTime", StoredValue = "2" });
_rawDictionary["Employee"]["Status"].Add(new ValuePair() { Name = "Retired", StoredValue = "3" });
BuildValueDictionary(_rawDictionary);
}
private void BuildValueDictionary(Dictionary<
string
, Dictionary<string, List<ValuePair>>> _rawDictionary)
{
// Get the current application domain for the current thread.
AppDomain currentDomain = AppDomain.CurrentDomain;
//// Create a dynamic assembly in the current application domain,
//// and allow it to be executed ONLY, NOT to be saved on disk!
AssemblyName aName = new AssemblyName("TempAssembly");
AssemblyBuilder ab = currentDomain.DefineDynamicAssembly(
aName, AssemblyBuilderAccess.Run);
// Define a dynamic module in "TempAssembly" assembly. For a single-
// module assembly, the module has the same name as the assembly.
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name);
foreach(var fieldEntry in _rawDictionary)
{
Dictionary<
string
, Type> valueTableDic = null;
if (!_enumDictionary.ContainsKey(fieldEntry.Key))
{
valueTableDic = new Dictionary<
string
, Type>();
_enumDictionary.Add(fieldEntry.Key, valueTableDic);
}
else
{
valueTableDic = _enumDictionary[fieldEntry.Key];
}
Dictionary<
string
, List<ValuePair>> rawEnumDict = fieldEntry.Value;
foreach (var fieldEnum in rawEnumDict)
{
// Define a public enumeration with the name "Elevation" and an
// underlying type of Integer.
EnumBuilder eb = mb.DefineEnum(fieldEnum.Key+"Enum", TypeAttributes.Public, typeof(int));
// build the enumerations
List<
ValuePair
> values = fieldEnum.Value;
foreach (var valuePair in values)
{
eb.DefineLiteral(valuePair.Name, int.Parse(valuePair.StoredValue));
}
// Create the type and save the assembly.
Type dynamicEnum = eb.CreateType();
// now put it in the value dictionary
valueTableDic[fieldEnum.Key] = dynamicEnum;
}
}
}
public Type getEnum(String tablename, String fieldname)
{
Type result = null;
if (_enumDictionary.ContainsKey(tablename))
{
Dictionary<
string
, Type> fieldDict = _enumDictionary[tablename];
if (fieldDict.ContainsKey(fieldname))
{
result = fieldDict[fieldname];
}
}
return result;
}
}
Basically, I want the dynamic Enum to have a popup like the static Enum, instead of PropertyGrid rendering it as a string.
Any help will be deeply appreciated!
Thanks in advance!