Я разрабатываю 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's DC - DialogControl just passes it through -->
</gui:DialogControl.Controls>
<gui:DialogControl.Buttons>
<!-- My dialog's 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 для окна как здесь , но опять же: Window имеет только один слот содержимого, поэтому в его шаблоне может быть только один докладчик, но мне нужно два (и если в этом случае можно было бы пойти с одним, есть другие варианты использования, когда несколько слотов контента подойдут, просто подумайте о шаблоне для статьи - пользователь элемента управления предоставит заголовок, (структурированный) контент, имя автора, изображение ...).
Спасибо!
PS: Если бы я хотел просто расположить кнопки рядом, как я могу разместить несколько элементов управления (кнопок) в StackPanel? ListBox имеет ItemsSource, а StackPanel - нет, и его свойство Children доступно только для чтения, поэтому это не работает (внутри пользовательского элемента управления):
<StackPanel
Orientation="Horizontal"
Children="{Binding Buttons}"/>
РЕДАКТИРОВАТЬ: я не хочу использовать привязку, так как я хочу назначить DataContext (ViewModel) всему окну (что равно View), а затем привязать к нему команды из кнопок, вставленных в `` слоты '' управления - поэтому любое использование привязка в иерархии нарушит наследование контроллера домена View.
Что касается идеи наследования от HeaderedContentControl - да, в этом случае это сработает, но что, если мне нужны три заменяемые части? Как мне создать свой собственный «HeaderedAndFooteredContentControl» (или как мне реализовать HeaderedContentControl, если бы у меня его не было)?
EDIT2: ОК, поэтому два моих решения не работают - вот почему: ContentPresenter получает свое содержимое из DataContext, но мне нужны привязки содержащихся элементов для ссылки на исходные окна '(родительский элемент UserControl в логическом дереве) DataContext - потому что таким образом, когда я встраиваю текстовое поле, привязанное к свойству ViewModel, оно не привязано, поскольку цепочка наследования была нарушена внутри элемента управления!
Кажется, что мне нужно сохранить родительский DataContext и восстановить его дочерним элементам всех контейнеров элементов управления, но я не получаю никакого события, что DataContext в логическом дереве изменился.
EDIT3: у меня есть решение! удалил свои предыдущие ответы. Смотрите мой ответ.