I am developing LOB application, where I will need multiple dialog windows (and displaying everything in one window is not an option/makes no sense).
I would like to have a user control for my window that would define some styling, etc., and would have several slots where content could be inserted - for example, a modal dialog window's template would have a slot for content, and for buttons (so that user can then provide a content and set of buttons with bound ICommands).
I would like to have something like this (but this doesn't work):
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>
Is something like this possible? How should I tell VS that my control exposes two content placeholders so that I can use it like this?
<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>
Or maybe I could use a ControlTemplate for a window like here, but then again: Window has only one content slot, therefore its template will be able to have only one presenter, but I need two (and if in this case it would po maybe possible to go with one, there are other use cases where several content slots would come hand, just think about a template for article - control's user would supply a title, (structured) content, author name, image...).
Thank you!
PS: If I wanted to just have buttons side by side, how can I put multiple controls (buttons) to StackPanel? ListBox has ItemsSource, but StackPanel has not, and it's Children property is read-only - so this doesn't work (inside the usercontrol):
<StackPanel
Orientation="Horizontal"
Children="{Binding Buttons}"/>
EDIT: I don't want to use binding, as I want to assign a DataContext (ViewModel) to a whole window (which equals View), and then bind to it's commands from buttons inserted into control 'slots' - so any use of binding in the hierarchy would break inheritance of View's DC.
As for the idea of inheriting from HeaderedContentControl - yes, in this case it would work, but what if I want three replacable parts? How do I make my own "HeaderedAndFooteredContentControl" (or, how would I implement HeaderedContentControl if I didn't have one)?
EDIT2: OK, so my two solutions doen't work - this is why: The ContentPresenter gets it's content from the DataContext, but I need the bindings on contained elements to link to original windows' (UserControl's parent in logical tree) DataContext - because this way, when I embed textbox bound to ViewModel's property, it is not bound, as the inheritance chain has been broken inside the control!
It seems that I would need to save parent's DataContext, and restore it to the children of all control's containers, but I don't get any event that DataContext up in the logical tree has changed.
EDIT3: I have a solution!, deleted my previous aswers. See my response.