Я разрабатываю приложение LOB, где мне понадобится несколько диалоговых окон (и отображение всего в одном окне не является опцией/не имеет смысла).
Я хотел бы иметь пользовательский элемент управления для моего окна, который бы определял некоторый стиль и т.д., и имел бы несколько слотов, в которые мог бы быть вставлен контент - например, модальный шаблон диалогового окна имеют слот для контента и для кнопок (так что пользователь может затем предоставить контент и набор кнопок со связанными ICommands).
Я хотел бы иметь что-то вроде этого (но это не работает):
UserControl xaml:
<UserControl x:Class="TkMVVMContainersSample.Services.Common.GUI.DialogControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
>
<DockPanel>
<DockPanel
LastChildFill="False"
HorizontalAlignment="Stretch"
DockPanel.Dock="Bottom">
<ContentPresenter ContentSource="{Binding Buttons}"/>
</DockPanel>
<Border
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
Padding="8"
>
<ContentPresenter ContentSource="{Binding Controls}"/>
</Border>
</DockPanel>
</UserControl>
Что-то вроде этого возможно? Как мне сказать VS, что мой элемент управления предоставляет два заполнителя содержимого, чтобы я мог использовать его следующим образом?
<Window ... DataContext="MyViewModel">
<gui:DialogControl>
<gui:DialogControl.Controls>
<!-- My dialog content - grid with textboxes etc...
inherits the Window DC - DialogControl just passes it through -->
</gui:DialogControl.Controls>
<gui:DialogControl.Buttons>
<!-- My dialog buttons with wiring, like
<Button Command="{Binding HelpCommand}">Help</Button>
<Button Command="{Binding CancelCommand}">Cancel</Button>
<Button Command="{Binding OKCommand}">OK</Button>
- they inherit DC from the Window, so the OKCommand binds to MyViewModel.OKCommand
-->
</gui:DialogControl.Buttons>
</gui:DialogControl>
</Window>
Или, может быть, я мог бы использовать ControlTemplate для окна как здесь, но опять же: окно имеет только один слот для контента, поэтому его шаблон сможет иметь только один ведущий, но мне нужно два (и если в этом случае возможно, возможно, с ним можно пойти, есть и другие варианты использования, в которых будет доступно несколько слотов контента, просто подумайте о шаблоне для пользователя, контролирующего статьи, (структурированный) контент, имя автора, изображение...).
Спасибо!
PS: Если бы я хотел просто иметь кнопки рядом, как я могу добавить несколько элементов управления (кнопок) в StackPanel? ListBox имеет ItemsSource, но StackPanel не имеет, и свойство Children доступно только для чтения - поэтому это не работает (внутри usercontrol):
<StackPanel
Orientation="Horizontal"
Children="{Binding Buttons}"/>
EDIT: я не хочу использовать привязку, так как я хочу назначить DataContext (ViewModel) на целое окно (которое равно View), а затем привязать к нему команды из кнопок, вставленных в "слоты" управления, - так любое использование привязки в иерархии нарушит наследование View DC.
Что касается идеи наследования с HeaderedContentControl - да, в этом случае это сработает, но что, если я хочу три заменяемые части? Как создать собственный "HeaderedAndFooteredContentControl" (или, как я могу реализовать HeaderedContentControl, если у меня его нет)?
EDIT2: ОК, поэтому мои два решения не работают - вот почему: ContentPresenter получает контент из DataContext, но мне нужны привязки к содержащимся элементам для ссылки на исходные окна (родительский элемент UserControl в логическом дереве) DataContext - потому что таким образом, когда я вставляю текстовое поле, связанное с свойством ViewModel, оно не связано, поскольку цепочка наследования была нарушена внутри элемента управления!
Кажется, мне нужно сохранить родительский DataContext и восстановить его для дочерних элементов всех контейнеров управления, но я не получаю никакого события, которое DataContext в логическом дереве изменилось.
EDIT3: у меня есть решение!, удалены мои предыдущие аверы. См. Мой ответ.