Hello! I found this discussion. 08 Oct 2014 Yoan says:
"I am afraid that this functionality is not supported since there are some conceptual impediments that prevent us to change the implementation of RadPropertyGrid. However, I have logged this in our system as feature request..."
Anyway, I spent a couple of hours and just put it here. All we need is:
- ControlTemplate of the PropertyGridFieldTemplate, defined in ResourceDictionary (Theme);
- NestedPropertyVisibilityBehavior
- PreventNestingAttribute
In the ControlTemplate find "PART_NestedPropertiesButton" and replace it with
<
t:RadToggleButton
x:Name
=
"PART_NestedPropertiesButton"
Style
=
"{StaticResource PropertyGridNestedToggleButtonStyle}"
Background
=
"Transparent"
Width
=
"25"
IsChecked
=
"{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsExpanded, Mode=TwoWay}"
>
<
i:Interaction.Behaviors
>
<
behaviors:NestedPropertyVisibilityBehavior
PropertyGridField
=
"{Binding RelativeSource={RelativeSource TemplatedParent}}"
ShouldDisplayNestedProperties
=
"{Binding ShouldDisplayNestedProperties, RelativeSource={RelativeSource TemplatedParent}}"
/>
</
i:Interaction.Behaviors
>
</
t:RadToggleButton
>
Behavior class:
public
class
NestedPropertyVisibilityBehavior : Behavior<RadToggleButton>
{
public
static
readonly
DependencyProperty PropertyGridFieldProperty =
DependencyProperty.Register(
"PropertyGridField"
,
typeof
(PropertyGridField),
typeof
(NestedPropertyVisibilityBehavior),
new
PropertyMetadata(
null
, OnPropertyGridFieldChanged));
public
static
readonly
DependencyProperty ShouldDisplayNestedPropertiesProperty =
DependencyProperty.Register(
"ShouldDisplayNestedProperties"
,
typeof
(
bool
),
typeof
(NestedPropertyVisibilityBehavior),
new
PropertyMetadata(
false
, OnShouldDisplayNestedPropertiesChanged));
private
bool
_preventNesting;
public
PropertyGridField PropertyGridField
{
get
{
return
(PropertyGridField)GetValue(PropertyGridFieldProperty); }
set
{ SetValue(PropertyGridFieldProperty, value); }
}
public
bool
ShouldDisplayNestedProperties
{
get
{
return
(
bool
)GetValue(ShouldDisplayNestedPropertiesProperty); }
set
{ SetValue(ShouldDisplayNestedPropertiesProperty, value); }
}
private
static
void
OnShouldDisplayNestedPropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var sender = (NestedPropertyVisibilityBehavior) d;
sender.UpdateVisibility();
}
private
static
void
OnPropertyGridFieldChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var field = e.NewValue
as
PropertyGridField;
if
(field ==
null
)
return
;
var propDef = field.DataContext
as
PropertyDefinition;
if
(propDef ==
null
)
return
;
var attrs = GetCustomAttributes(propDef.Instance, propDef.SourceProperty.Name);
var sender = (NestedPropertyVisibilityBehavior) d;
sender._preventNesting = attrs.Any(x => x
is
PreventNestingAttribute);
sender.UpdateVisibility();
}
protected
override
void
OnAttached()
{
UpdateVisibility();
}
private
void
UpdateVisibility()
{
if
(AssociatedObject ==
null
)
return
;
AssociatedObject.Visibility = ShouldDisplayNestedProperties && !_preventNesting
? Visibility.Visible
: Visibility.Collapsed;
}
protected
static
object
[] GetCustomAttributes(
object
source,
string
propertyPath)
{
if
(source ==
null
||
string
.IsNullOrEmpty(propertyPath))
return
null
;
PropertyInfo propertyInfo =
null
;
var currentType = source.GetType();
var path = propertyPath.Split(
'.'
);
for
(
int
i = 0, count = path.Length; i < count; i++)
{
var propertyStep = path[i];
propertyInfo = currentType.GetProperty(propertyStep);
if
(propertyInfo ==
null
|| source ==
null
|| i == count - 1)
break
;
source = propertyInfo.GetValue(source,
null
);
currentType = propertyInfo.PropertyType;
}
return
propertyInfo !=
null
? propertyInfo.GetCustomAttributes(
true
) :
null
;
}
}
Attribute:
[AttributeUsage(AttributeTargets.Property)]
public
sealed
class
PreventNestingAttribute : Attribute { }
Usage in your Settings item:
[PreventNesting]
//[Display(Name = "Margin")]
public
Thickness Margin
{
get
{
return
_margin;
}
set
{ Set(() => Margin,
ref
_margin, value); }
}
I would be happy if it can be made more compact. I made it in haste.
Microsoft Silverlight (64-bit) Version: 5.1.41105.0
Windows 8.1 (64-bit)
Internet Explorer 11.0.9600.17416
Telerik 2017.1.117.1050