Я хочу создать элемент WPF, который во время выполнения полностью контролирует свои дочерние элементы - добавляя и удаляя дочерний интерфейс при изменении его свойств. Нечто похожее на то, что делает ItemsControl при изменении его свойства ItemsSource, хотя в моем случае будет только один дочерний элемент.
Это будет контейнер представления для MVVM - когда вы дадите ему Model или ViewModel, он волшебным образом создаст правильный View и соединит все. Нет необходимости, чтобы мой контейнер вида был изменяемым (поскольку он создает определяемые пользователем представления, которые являются пользовательскими элементами управления и имеют свои собственные шаблоны), и я бы предпочел, чтобы он как можно больше инкапсулировал. Я мог бы легко сделать это, спустившись с чего-то вроде Grid, и добавив дочерние элементы управления, когда мои собственные свойства изменятся; но Grid публично предоставляет свою коллекцию дочерних элементов и позволяет любому добавлять и удалять вещи.
Из какого класса WPF мне следует спуститься для максимальной инкапсуляции и как добавить к нему дочерние элементы во время выполнения?
Основываясь на своем понимании документов, я попытался использовать FrameworkElement и AddVisualChild, просто чтобы посмотреть, смогу ли я создать дочерние элементы управления во время выполнения. Мне не ясно, нужен ли AddLogicalChild, но я добавил его на всякий случай:
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;
}
}
Когда я помещаю ViewContainer в окно и запускаю его, я ожидаю увидеть TextBlock с надписью «ViewContainer». Но вместо этого я просто вижу пустое окно. Очевидно, я что-то упускаю.
Как я могу исправить вышеприведенный код, чтобы «дочерний» элемент управления появлялся во время выполнения, но не был доступен для других пользователей (больше, чем можно избежать)?