This is a migrated thread and some comments may be shown as answers.

FlagEnumEditor does not work if mutlple Item is set to RadPropertyGrid:SourceItems

3 Answers 90 Views
PropertyGrid
This is a migrated thread and some comments may be shown as answers.
Shinya
Top achievements
Rank 1
Shinya asked on 11 Mar 2019, 02:10 AM

Method to reproduce 
(telerik version 2018.1.220)

  1. Create a structure that has enum with [Flags] attribute as members
  2. Set the array of the above structure to SourceItems of RadPropertyGrid
  3. Set "Intersection" or "Union" for "PropertySetMode" of "RadProeprtyGrid"
  4. Run the application
  5. Changing enum member flags from PropertyGrid with FlagEnumEditor will not be applied.
    In addition, the following exception occurs when changing the flag

---
Exception thrown: 'System.InvalidCastException' in mscorlib.dll
Exception thrown: 'System.InvalidCastException' in mscorlib.dll
Exception thrown: 'System.Reflection.TargetInvocationException' in mscorlib.dll
System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=CurrentPropertySet[Types]; DataItem='PropertySetViewModel' (HashCode=30131813); target element is 'FlagEnumEditor' (Name=''); target property is 'Value' (type 'Object') InvalidCastException:'System.InvalidCastException: 'System.String' から 'enum_flags_test.MainWindow+EnumTest+Type' への無効なキャストです。
   System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
   System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)
   System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   Telerik.Windows.Controls.RadPropertyGrid.<>c__DisplayClass2b.<OnPropertySetViewModelChanged>b__28(Object s, PropertyChangedEventArgs e)
   System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)
   Telerik.Windows.Controls.Data.PropertyGrid.PropertySet.OnPropertyChanged(String fileName)
   Telerik.Windows.Controls.Data.PropertyGrid.PropertySet.set_Item(String property, Object value)'

---

Is there any workaround? 
Your help would be welcomed.

 

---

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public class EnumTest
    {
        [Flags]
        public enum Type
        {
            None = 0,
            First = 1 << 0,
            Second = 1 << 1,
        }
 
        public Type Types { get; set; } = Type.None;
    }
 
 
    public MainWindow()
    {
        InitializeComponent();
 
        PropertyGrid1.Item = new EnumTest[] { new EnumTest() };
    }
}

 

MainWindow.xaml

<Window x:Class="enum_flags_test.MainWindow"
        xmlns:local="clr-namespace:enum_flags_test"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
        <telerik:RadPropertyGrid
            x:Name="PropertyGrid1"
            PropertySetMode="Intersection"/>
    </Grid>
</Window>

 


3 Answers, 1 is accepted

Sort by
0
Accepted
Dilyan Traykov
Telerik team
answered on 13 Mar 2019, 01:57 PM
Hello Shinya,

Thank you for the exhaustive action steps, code snippets and provided error output.

I've prepared a small sample project demonstrating a possible approach for this specific scenario. It involves creating a custom editor template as shown in this article and using a converter to parse the enum values correctly.

Please have a look and let me know whether this would work for you.

Regards,
Dilyan Traykov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Shinya
Top achievements
Rank 1
answered on 22 Mar 2019, 01:42 AM

Thank you for your reply and great sample.
The sample gave me a clue and I was able to solve the problem.

In our issue, class and enum are variable, so , I changed so that the process will use Code Behind instead of xaml.

The code is described below.
Please let me know if you see any problems.

Thank you very much again.

 

---

MainWindow.xaml.cs

01.public partial class MainWindow : Window
02.{
03.    public class EnumTest
04.    {
05.        [Flags]
06.        public enum Type
07.        {
08.            None = 0,
09.            First = 1 << 0,
10.            Second = 1 << 1,
11.        }
12. 
13.        public Type Types { get; set; }
14.    }
15. 
16. 
17.    public MainWindow()
18.    {
19.        InitializeComponent();
20. 
21.        PropertyGrid1.AutoGeneratingPropertyDefinition += PropertyGrid1_AutoGeneratingPropertyDefinition;
22.        PropertyGrid1.Item = new EnumTest[] { new EnumTest() };
23.    }
24. 
25.    private void PropertyGrid1_AutoGeneratingPropertyDefinition(object sender, AutoGeneratingPropertyDefinitionEventArgs e)
26.    {
27.        var prop = e.PropertyDefinition.SourceProperty;
28.        var propType = prop.PropertyType;
29. 
30.        if (propType.IsEnum && propType.GetCustomAttributes(typeof(FlagsAttribute), false).Any())
31.        {
32.            var flagEnumEditor = new FrameworkElementFactory(typeof(FlagEnumEditor));
33.            flagEnumEditor.SetValue(FlagEnumEditor.EnumTypeProperty, prop.PropertyType);
34.            flagEnumEditor.SetBinding(FlagEnumEditor.ValueProperty, new Binding($"CurrentPropertySet[{ e.PropertyDefinition.DisplayName }]") { Mode = BindingMode.TwoWay, Converter = new EnumConverter(propType) });
35. 
36.            var dataTemplate = new DataTemplate();
37.            dataTemplate.VisualTree = flagEnumEditor;
38.            dataTemplate.Seal();
39. 
40.            e.PropertyDefinition.EditorTemplate = dataTemplate;
41.        }
42.    }
43.}
44. 
45.public class EnumConverter : IValueConverter
46.{
47.    Type _enumType;
48. 
49.    public EnumConverter(Type enumType)
50.    {
51.        _enumType = enumType;
52.    }
53. 
54.    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
55.    {
56.        try
57.        {
58.            var strVal = value.ToString() == "0" ? "" : value.ToString();
59.            var enumVal = Enum.Parse(_enumType, strVal);
60.            return strVal;
61.        }
62.        catch (Exception) { }
63. 
64.        return "";
65.    }
66. 
67.    public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
68.    {
69.        try
70.        {
71.            var strVal = String.IsNullOrEmpty(value.ToString()) ? "None" : value.ToString();
72.            var enumVal = Enum.Parse(_enumType, strVal);
73.            return enumVal;
74.        }
75.        catch (Exception) { }
76. 
77.        return Enum.ToObject(_enumType, 0);
78.    }
79.}
0
Dilyan Traykov
Telerik team
answered on 22 Mar 2019, 03:50 PM
Hello Shinya,

I'm glad to hear that you were able to find a suitable solution. I don't see any problems with the implementation you've chosen, but should you come across any issues, do not hesitate to contact me again.

Regards,
Dilyan Traykov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
PropertyGrid
Asked by
Shinya
Top achievements
Rank 1
Answers by
Dilyan Traykov
Telerik team
Shinya
Top achievements
Rank 1
Share this question
or