Como criar dois dados hierárquicos que são mutuamente referenciais no Silverlight?
-
25-09-2019 - |
Pergunta
Dado que:
- DatAtemplates não podem ser atribuídos pelo TargetType
- As referências StaticResource só podem referenciar anteriormente
Como um modelo é a seguinte situação em uma View Tree?
class Resource {
public string Name {get;}
public IEnumerable<Property> Properties {get;}
}
class Property {
public string Name {get;}
public IEnumerable<Resource> Values {get;}
}
Essa estrutura se presta bem a uma árvore que seria:
Resource 1
|- Property A
| - Resource 2
| - Resource 3
|- Property B
|- Resource 4
Isso seria trivial para modelar no WPF por causa do TargetType
propriedade de HierarchicalDataTemplate
. Em Silverlight, teríamos que fazer algo mais como:
<HierarchicalDataTemplate x:Key="ResourceTemplate"
ItemSource="{Binding Properties}"
ItemTemplate={StaticResource PropertyTemplate}" />
<HierarchicalDataTemplate x:Key="PropertyTemplate"
ItemSource="{Binding Values}"
ItemTemplate="{StaticResource ResourceTemplate}" />
O que obviamente não pode funcionar porque ResourceTemplate
não posso referir PropertyTemplate
Porque é definido após ele no documento XAML. Então, como você resolve esse problema de frango e ovo?
Solução
A única solução razoável que encontrei é criar um terceiro tipo de viewmodel que envolveria um dos dois primeiros tipos (recursos ou propriedades) e forneça propriedades comuns para se ligar a: (por exemplo, crianças). Isso ainda não é muito ideal, no entanto, se os dois tipos precisarem de modelos muito diferentes, porque nesse ponto, estou usando o VisualStateManager
Para alternar entre os modelos para os dados.
<HierarchicalDataTemplate x:Key="TreeItemTemplate"
ItemSource="{Binding Children}">
<ContentPresenter Content="{Binding}">
<VisualStateManager.Groups>
<VisualStateGroup>
<VisualState Name="IsResource">
<!-- set resource template -->
</VisualState>
<VisualState Name="IsProperty">
<!-- set property template -->
</VisualState>
</VisualStateGroup>
</VisualStateManager.Groups>
</ContentPresenter>
</HierarchicalDataTemplate>