Question

Je veux créer un élément WPF qui, lors de l'exécution, est en plein contrôle de ses éléments enfants - ajout et la suppression de l'interface utilisateur enfant lorsque ses propriétés changement. Quelque chose un peu comme ce ItemsControl fait quand vous modifiez sa propriété ItemsSource, mais dans mon cas, il n'y aura que un enfant.

Ce sera un conteneur de vue pour MVVM - quand vous donnez un modèle ou un ViewModel, il va créer comme par magie le tout correct Affichage et câbler. Il n'y a pas besoin de mon conteneur en vue d'être templatable (car il crée des vues définies par l'utilisateur, qui sont UserControls et ont leurs propres modèles), et je préfère que ce encapsulent autant que possible. Je pourrais probablement le faire facilement en descendant de quelque chose comme la grille, et l'ajout de contrôles de l'enfant lorsque mes propres propriétés changent; mais la grille expose publiquement sa collection d'éléments enfants et permet d'ajouter de tout le monde et supprimer des choses.

Quelle classe WPF dois-je descendre pour l'encapsulation maximale, et comment puis-je ajouter des éléments d'enfant à elle lors de l'exécution?

D'après ma compréhension des documents, j'ai essayé d'utiliser FrameworkElement et AddVisualChild, juste pour voir si je pouvais créer des contrôles de l'enfant lors de l'exécution. Je ne comprends pas si le AddLogicalChild est nécessaire, mais je mets en juste au cas où:

public class ViewContainer : FrameworkElement {
    private TextBlock _child;

    public ViewContainer() {
        _child = new TextBlock { Text = "ViewContainer" };
        AddLogicalChild(_child);
        AddVisualChild(_child);
        InvalidateMeasure();
    }

    public object Content { get; set; }

    protected override Size ArrangeOverride(Size finalSize) {
        _child.Arrange(new Rect(finalSize));
        return finalSize;
    }
    protected override Size MeasureOverride(Size availableSize) {
        _child.Measure(availableSize);
        return _child.DesiredSize;
    }
}

Quand je mets un ViewContainer dans une fenêtre et exécuter cela, je me attends à un TextBlock dire « ViewContainer ». Mais au contraire, je vois juste une fenêtre vide. Alors, évidemment, je manque quelque chose.

Comment puis-je corriger le code ci-dessus afin que le « enfant » contrôle ne semble à l'exécution, mais il est pas exposé à d'autres de jouer avec (plus que ce qui peut être évité)?

Était-ce utile?

La solution

Pour répondre à votre question spécifique, vous aurez également besoin override GetVisualChild et les propriétés de VisualChildrenCount pour permettre à votre élément enfant à afficher.

Autres conseils

Avez-vous pensé à tirer profit du soutien de WPF pour DataTemplates implicites?

La façon dont je l'ai traité une exigence semblable à la vôtre est à l'aide d'un ContentControl. Je lie la propriété Content à mon ViewModel. Je puis assurez-vous que dans des ressources dictionnaires référencé quelque part dans l'arbre au-dessus du ContentControl je DataTemplates définis pour tous les types de ViewModels qui pourraient être affectés à la propriété de contenu.

De cette façon WPF prend en charge le câblage jusqu'à la vue correcte pour mon ViewModel.

scroll top