benbants
benbants

Reputation: 608

WPF - How to persist current content when setting the content property

I'm facing a problem where by setting the content property of my window I obviously remove pre-existing content. On all windows I have a dockpanel that I use to pop up help contextual help to the user but this is lost when I set the content property of the window. Therefore I will only see the content for the control I've added and pressing F1 does nothing as the dockpanel does not exist. I don't want to add this dockpanel to every control as it's poor code-reuse so what can I do to keep the dockpanel on the window and add content without overwriting original content of the window?

This is the code where I set the content of the window.

private void btnHelp_Click(object sender, RibbonControlEventArgs e)
    {
        System.Windows.Window window = new ResizeableWindow()
        {
            Title = "Help",
            Content = new Controls.Help(),
            ResizeMode = ResizeMode.NoResize

        };

        window.ShowDialog();
    }

This is code for my Help control it's just a document viewer to read an xps document, this is used by the dockpanel.

public partial class Help : UserControl
{
    public Help()
    {
        InitializeComponent();

        string appPath = "path";

        XpsDocument doc = new XpsDocument(appPath, FileAccess.Read);

        var docx = doc.GetFixedDocumentSequence();

        HelpDocViewer.Document = docx;
    }
}

This is the xaml of my ResizableWindow containing the Dockpanel

<Window x:Class="Controls.ResizeableWindow"           
        KeyDown="HelpKeyListen">   

    <Grid>
        <DockPanel x:Name="HelpPanel">

        </DockPanel>

    </Grid>       

</Window>

Here is the code for the resizeable window

public ResizeableWindow()
    {
        InitializeComponent();
    }

    private void HelpKeyListen(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.F1)
        {
            var HelpControl = new Help();
            DockPanel.SetDock(HelpControl, Dock.Right);
            HelpPanel.Children.Insert(0, HelpControl);
        }
    }

Upvotes: 0

Views: 297

Answers (1)

grek40
grek40

Reputation: 13458

Use Placeholders inside the DockPanel instead of replacing the window content:

<DockPanel x:Name="HelpPanel">
    <ContentControl x:Name="HelpContent" DockPanel.Dock="Right"/>
    <ContentControl x:Name="MainContent"/>
</DockPanel>

Then assign the contents of the contentcontrols as needed

private void HelpKeyListen(object sender, KeyEventArgs e)
{
    if (e.Key == Key.F1)
    {
        HelpContent.Content = new Help();
    }
}

Possibly create a new dependency property in ResizeableWindow if you want to provide main content from the outside. Lets say you add a dependency property (visual studio code snipped propdp) named MainContent, then you can bind it as follows:

<DockPanel x:Name="HelpPanel">
    <ContentControl x:Name="HelpContent" DockPanel.Dock="Right"/>
    <ContentControl x:Name="MainContentPlaceholder" Content="{Binding MainContent,RelativeSource={RelativeSource AnchestorType=Window}}"/>
</DockPanel>

The more appropriate option would be to replace the MainContentPlaceholder by some more WPF/MVVM friendly way to display your contents, but thats out of scope for the question.

Upvotes: 1

Related Questions