Я хочу создать элемент WPF, который во время выполнения полностью контролирует свои дочерние элементы — добавляя и удаляя дочерний пользовательский интерфейс при изменении его свойств. Что-то вроде того, что делает ItemsControl, когда вы изменяете его свойство ItemsSource, хотя в моем случае будет только один дочерний элемент.
Это будет контейнер представления для MVVM — когда вы дадите ему модель или модель представления, он волшебным образом создаст правильное представление и подключит все. Нет необходимости, чтобы мой контейнер представления был шаблонным (поскольку он создает определяемые пользователем представления, которые являются пользовательскими элементами управления и имеют свои собственные шаблоны), и я бы предпочел, чтобы он инкапсулировал как можно больше. Вероятно, я мог бы легко сделать это, наследуя что-то вроде 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». Но вместо этого я просто вижу пустое окно. Так что, очевидно, я что-то упускаю.
Как я могу исправить приведенный выше код, чтобы «дочерний» элемент управления отображался во время выполнения, но не был доступен для других (больше, чем можно было бы избежать)?