Я занимаюсь разработкой 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), а затем привязать его команды от кнопок, вставленных в «слоты» управления - так любое использование привязки в иерархии нарушило бы наследование DC представления.
Что касается идеи наследования от HeaderedContentControl - да, в этом случае это будет работать, но что, если я хочу три сменные части? Как мне создать свой собственный «HeaderedAndFooteredContentControl» (или как мне реализовать HeaderedContentControl, если у меня его нет) ?
EDIT2: ОК, поэтому мои два решения не работают - вот почему:
ContentPresenter получает свое содержимое из DataContext, но мне нужно, чтобы привязки к содержащимся элементам связывались с исходными окнами (родительский элемент UserControl в логическом дереве) DataContext - потому что таким образом, когда я встраиваю текстовое поле, связанное со свойством ViewModel, оно не привязывается как цепочка наследования разорвана внутри элемента управления !
Кажется, мне нужно сохранить DataContext родительского элемента и восстановить его для потомков всех контейнеров элемента управления, но я не получаю никакого события, когда DataContext в логическом дереве изменился.
РЕДАКТИРОВАТЬ3: У меня есть решение! , удалил мои предыдущие aswers.
Смотрите мой ответ.