Reputation: 12804
I have a sidebar in an application I am writing that displays information about the application's state to the user. In certain cases, the user can hover over various elements in the sidebar to view more specific details. These details are shown to the user using a control that mimics the behavior of Bootstrap's Popover
control. I accomplish this using an invisible Canvas
overlay that spans the entire window, and the "Popover" itself is placed relatively on this Canvas
using computed Canvas.Left
and Canvas.Top
properties.
Here's a (very simplified) look at the current XAML of my application:
<Window>
<Grid x:Name="container">
<.. a lot of various nested elements ..>
<StackPanel x:Name="sidepanel">
.. content of the sidepanel control ..
</StackPanel>
</.. a lot of various nested elements ..>
<Canvas x:Name="overlay">
.. content of the Popover control ..
</Canvas>
</Grid>
</Window>
This works great, except that I'd like to refactor this functionality into a single control. However, I'm not sure how to proceed - if the custom UserControl
includes the Canvas
overlay in its XAML definition, I'll be unable to position the sidepanel portion of the control in the same way as it currently is positioned within the application. However, the Canvas
overlay can't be nested inside of the sidepanel, as it needs to span the entire window in order to operate properly.
Is there a way to define a single UserControl
that can sit in different parts of the logical tree? Or is there a better way to accomplish this effect?
Upvotes: 2
Views: 820
Reputation: 24453
You can't split a single UserControl
into different places in the logical tree, but you can inject other code into a Control
and place it around the internal components it defines. This is the model used by HeaderedContentControl
: two content properties, Content
and Header
, which are injected into two different ContentPresenters
in the control's template. Hence things like Expander
and TabItem
with externally defined content in multiple locations around intrinsic parts of the controls. In the case of a UserControl
you would be placing them in the main XAML instead of a template so the bindings are a little different but the principle is the same.
Define two Dependency properties of type object on your UserControl
and then bind those into ContentPresenters
placed in the exact spots where you have "a lot of various nested elements" in your sample. Then when you use the UserControl
you can just define whatever other elements you want under the UserControl
element inside like <MyUserControl.MyContentProperty1>
tags and they'll get placed inside your UserControl
content.
Upvotes: 1