Nathan Friend
Nathan Friend

Reputation: 12804

UserControl that includes full window overlay

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

Answers (1)

John Bowen
John Bowen

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

Related Questions