Incorrect editors when switching PropertySetMode

3 posts, 0 answers
  1. Chris
    Chris avatar
    18 posts
    Member since:
    Sep 2014

    Posted 09 Nov 2015 Link to this post

    I'm experiencing some odd behavior when changing the PropertySetMode at runtime. 

     

    I have two object types: MyTestClass1 and MyTestClass2. MyTestClass1 has a writeable property IntProp and MyTestClass2 has a readonly property IntProp. If I start in Intersection mode with Item = List<Object> { myTestClass1Obj1, myTestClass1Obj2 } everything works properly. If I then change to PropertySetMode None with Item = myTestClass2Obj, the editor for IntProp will be writeable even though IntProp on myTestClass2Obj has no public setter.

     

    See runnable test case below. I am running 2015.2.728

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"       
            Title="MainWindow" Height="350" Width="525">
        <Grid>
        <StackPanel Orientation="Vertical">
          <Button Click="ButtonBase_OnClick">Change to mode none</Button>
          <telerik:RadPropertyGrid x:Name="rpg"/>
        </StackPanel>
      </Grid>
    </Window>

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.ComponentModel;
    using System.Collections.ObjectModel;
    using System.Text.RegularExpressions;
    using System.ComponentModel.DataAnnotations;
    using Telerik.Windows.Controls.Data.PropertyGrid;
     
    namespace WpfApplication1
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
          private readonly MyTestClass test;
        private readonly MyTestClass test2;
        private readonly MyTestClass2 test3;
     
        public MainWindow()
            {
                InitializeComponent();
                rpg.AutoGeneratingPropertyDefinition += new EventHandler<Telerik.Windows.Controls.Data.PropertyGrid.AutoGeneratingPropertyDefinitionEventArgs>(rpg_AutoGeneratingPropertyDefinition);
     
          // test data. IntProp is has a public setter
          test = new MyTestClass() { StringProp = "91das", RequiredField = "abc", IntProp = 10, DateTimeProp = new DateTime(1920, 2, 21) };
          test2 = new MyTestClass() { StringProp = "91das", RequiredField = "abc", IntProp = 10, DateTimeProp = new DateTime(1920, 2, 21) };
     
          // test data. IntProp is read only (no public setter)
          test3 = new MyTestClass2() { StringProp = "91das", RequiredField = "abc", DateTimeProp = new DateTime(1920, 2, 21) };
     
          rpg.Item = new List<Object> {test, test2};
          rpg.PropertySetMode = PropertySetOperation.Intersection;
            }
     
            void rpg_AutoGeneratingPropertyDefinition(object sender, Telerik.Windows.Controls.Data.PropertyGrid.AutoGeneratingPropertyDefinitionEventArgs e)
            {
                (e.PropertyDefinition.Binding as Binding).ValidatesOnDataErrors = true;
                (e.PropertyDefinition.Binding as Binding).NotifyOnValidationError = true;
                (e.PropertyDefinition.Binding as Binding).ValidatesOnExceptions = true;
            }
     
            private ObservableCollection<ValidationError> results;
     
            public ObservableCollection<ValidationError> Results
            {
                get
                {
                    if (this.results == null)
                    {
                        this.results = new ObservableCollection<ValidationError>();
                    }
                    return results;
                }
            }
         
        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
          rpg.PropertySetMode = PropertySetOperation.None;
          rpg.Item = test3;
          // the property grid will now allow setting of test3.IntProp even though there is
          // no public setter
        }
      }
     
     
        public class MyTestClass : IDataErrorInfo, INotifyPropertyChanged
        {
             
            private int intVar;
            private string requiredField;
     
            public int IntProp
            {
                get { return intVar; }
                set
                {
                    intVar = value;
                    this.OnPropertyChanged("IntProp");
                }
            }
     
            [Required(ErrorMessage = "This field is Required.")]
            public string RequiredField
            {
                get { return requiredField; }
                set
                {
                    requiredField = value;
                    ValidateProperty("RequiredField", value);
                    this.OnPropertyChanged("RequiredField");
                }
            }
     
            private string stringVar;
     
            public string StringProp
            {
                get { return stringVar; }
                set
                {
                    stringVar = value;
                    this.OnPropertyChanged("StringProp");
                }
            }
     
            private DateTime dateTimeVar;
     
            public DateTime DateTimeProp
            {
                get { return dateTimeVar; }
                set
                {
                    dateTimeVar = value;
                    this.OnPropertyChanged("DateTimeProp");
                }
            }
     
            [Browsable(false)]
            public string Error
            {
                get { return string.Empty; }
            }
     
            public string this[string columnName]
            {
                get
                {
                    if (columnName == "IntProp")
                    {
                        return this.IntProp < 100 && this.IntProp > 0 ? string.Empty : "Value should be in the range of (0, 100)";
                    }
                    if (columnName == "StringProp")
                    {
                        return this.StringProp != null && Regex.IsMatch(this.StringProp, @"^[0-9]+[\p{L}]*") ? string.Empty : @"Value should math the regex: ^[0-9]+[\p{L}]*";
                    }
                    if (columnName == "DateTimeProp")
                    {
                        return this.DateTimeProp.Year > 1900 ? string.Empty : "Date should be after 1/1/1900";
                    }
                    return string.Empty;
                }
            }
     
            protected void OnPropertyChanged(string name)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(name));
                }
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
     
            public void ValidateProperty(string propName, object value)
            {
                var result = new List<System.ComponentModel.DataAnnotations.ValidationResult>();
                Validator.TryValidateProperty(value, new ValidationContext(this, null, null) { MemberName = propName }, result);
     
                if (result.Count > 0)
                {
                   throw new ValidationException(result[0].ErrorMessage);
                }
            }
        }
     
     
      public class MyTestClass2 : IDataErrorInfo, INotifyPropertyChanged
      {
     
        private int intVar;
        private string requiredField;
     
        public int IntProp { get; } = 12;
     
        [Required(ErrorMessage = "This field is Required.")]
        public string RequiredField
        {
          get { return requiredField; }
          set
          {
            requiredField = value;
            ValidateProperty("RequiredField", value);
            this.OnPropertyChanged("RequiredField");
          }
        }
     
        private string stringVar;
     
        public string StringProp
        {
          get { return stringVar; }
          set
          {
            stringVar = value;
            this.OnPropertyChanged("StringProp");
          }
        }
     
        private DateTime dateTimeVar;
     
        public DateTime DateTimeProp
        {
          get { return dateTimeVar; }
          set
          {
            dateTimeVar = value;
            this.OnPropertyChanged("DateTimeProp");
          }
        }
     
        [Browsable(false)]
        public string Error
        {
          get { return string.Empty; }
        }
     
        public string this[string columnName]
        {
          get
          {
            if (columnName == "IntProp")
            {
              return this.IntProp < 100 && this.IntProp > 0 ? string.Empty : "Value should be in the range of (0, 100)";
            }
            if (columnName == "StringProp")
            {
              return this.StringProp != null && Regex.IsMatch(this.StringProp, @"^[0-9]+[\p{L}]*") ? string.Empty : @"Value should math the regex: ^[0-9]+[\p{L}]*";
            }
            if (columnName == "DateTimeProp")
            {
              return this.DateTimeProp.Year > 1900 ? string.Empty : "Date should be after 1/1/1900";
            }
            return string.Empty;
          }
        }
     
        protected void OnPropertyChanged(string name)
        {
          if (this.PropertyChanged != null)
          {
            this.PropertyChanged(this, new PropertyChangedEventArgs(name));
          }
        }
     
        public event PropertyChangedEventHandler PropertyChanged;
     
        public void ValidateProperty(string propName, object value)
        {
          var result = new List<System.ComponentModel.DataAnnotations.ValidationResult>();
          Validator.TryValidateProperty(value, new ValidationContext(this, null, null) { MemberName = propName }, result);
     
          if (result.Count > 0)
          {
            throw new ValidationException(result[0].ErrorMessage);
          }
        }
      }
    }
     

     

    dafadsf

  2. Stefan Nenchev
    Admin
    Stefan Nenchev avatar
    391 posts

    Posted 12 Nov 2015 Link to this post

    Hello Chris,

    I have reproduced the scenario you explained and after some further investigation from my end I can confirm there is an issue when updating the PropertySetMode at runtime. I have logged this behavior as a bug and you can follow it on our Ideas and Feedback Portal.  You can click on "Following this item"  in order to subscribe for notifications. I have also added 1000 Telerik points to your account as a compliment for reporting the matter.

    Regards,
    Stefan Nenchev
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. Chris
    Chris avatar
    18 posts
    Member since:
    Sep 2014

    Posted 12 Nov 2015 in reply to Stefan Nenchev Link to this post

    Thanks Stefan
Back to Top