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!
