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:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
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