I hope that someone will find this as useful as it can be.
Purpose:
Can apply many StyleSelectors to one item by cascade.
public
abstract
class
NestedStyleSelector : StyleSelector
{
public
StyleSelector ChildStyleSelector {
get
;
set
; }
// Use this instead of the SelectStyle method
//
public
abstract
Style GetStyle(
object
item, DependencyObject container);
public
sealed
override
Style SelectStyle(
object
item, DependencyObject container)
{
Style currentStyle = GetStyle(item, container),
childStyle =
null
;
if
(ChildStyleSelector !=
null
)
{
childStyle = ChildStyleSelector.SelectStyle(item, container);
}
if
(childStyle !=
null
)
{
if
(currentStyle !=
null
&& currentStyle.TargetType != childStyle.TargetType)
throw
new
InvalidOperationException();
var clonnedStyle =
new
Style(childStyle.TargetType)
{
BasedOn = currentStyle
};
foreach
(var setterBase
in
childStyle.Setters)
{
var setter = setterBase
as
Setter;
if
(setter ==
null
)
continue
;
clonnedStyle.Setters.Add(
new
Setter
{
Property = setter.Property,
Value = setter.Value
});
}
currentStyle = clonnedStyle;
}
return
currentStyle ??
base
.SelectStyle(item, container);
}
}
Usage in child implementations:
<!-- Some class, that implements the NestedStyleSelector -->
<
c:NestedStyleSelector
>
<
c:NestedStyleSelector.ChildStyleSelector
>
<!-- Any another style selector -->
</
cNestedStyleSelector.ChildStyleSelector
>
</
c:NestedStyleSelector
>
Restrictions:
- TargetType of all styles in chain must equals with it's parent returned style TargetType.
- Setter in choosen style of Child StyleSelector overrides the same property of parent style selector.
- BasedOn can be specified only in a first node declaration.
It works for me when I combine decisions, which row can be expanded and wich row has alternating background.
Sorry for my English :)