WPF: шаблон или UserControl с 2 (или более!) ContentPresenters для представления контента в «слотах»
Я занимаюсь разработкой LOB-приложения, в котором мне понадобится несколько диалоговых окон (и отображение всего в одном окне не вариант / не имеет смысла).
Я хотел бы иметь пользовательский элемент управления для моего окна, который определит некоторые стили и т. Д., И будет иметьseveral слоты, в которые может быть вставлен контент - например, шаблон модального диалогового окна будет иметь слот для контента и для кнопок (чтобы пользователь мог затем предоставить контент и набор кнопок со связанными ICommands).
Я хотел бы иметь что-то вроде этого (но это не работает):
UserControl xaml:
<code><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> </code>
Возможно ли что-то подобное? Как мне сообщить VS, что мой элемент управления предоставляет два заполнителя содержимого, чтобы я мог использовать его следующим образом?
<code><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> </code>
Или, может быть, я мог бы использовать ControlTemplate для окнакак здесь, но опять же: Window имеет только один слот контента, поэтому в его шаблоне может быть только один докладчик, но мне нужно два (и если в этом случае было бы возможно пойти с одним, есть другие случаи использования, когда подойдет несколько слотов контента, просто подумайте о шаблоне для пользователя, управляющего статьями, который предоставит заголовок, (структурированный) контент, имя автора, изображение ...).
Спасибо!
PS: Если бы я хотел, чтобы кнопки располагались рядом, как я могу разместить несколько элементов управления (кнопок) в StackPanel? ListBox имеет ItemsSource, а StackPanel - нет, и его свойство Children доступно только для чтения, поэтому это не работает (внутри usercontrol):
<code><StackPanel Orientation="Horizontal" Children="{Binding Buttons}"/> </code>
РЕДАКТИРОВАТЬ: я не хочу использовать привязку, так как я хочу назначить DataContext (ViewModel) всему окну (что равно View), а затем привязать к нему команды от кнопок, вставленных в слоты управления. - поэтому любое использование привязки в иерархии нарушило бы наследование DC представления.
Что касается идеи наследования от HeaderedContentControl - да, в этом случае это будет работать, но что, если я хочу три сменные части? Как мне создать свой собственный & quot; HeaderedAndFooteredContentControl & quot;(or, how would I implement HeaderedContentControl if I didn't have one)?
EDIT2: OK, so my two solutions doen't work - this is why: ContentPresenter получает его содержимое из DataContext, но мне нужны привязки для содержащихся элементов, чтобы связать их с исходными окнами. (Родитель UserControl в логическом дереве) DataContext - потому что таким образом, когда я встраиваю текстовое поле, привязанное к свойству ViewModel, оно не привязывается, так какthe inheritance chain has been broken inside the control!
Кажется, что мне нужно было бы сохранить родительский DataContext и восстановить его для потомков всех контейнеров элемента управления, но я не получаю никакого события, когда DataContext в логическом дереве изменился.
EDIT3: I have a solution!, удалил мои предыдущие ответы. Смотрите мой ответ.