Simple popup dialog in WPF (overlay inside Window)

12,152

The content of your Popup should be defined as a ControlTemplate for the ContentPresenter to work as expected here. Please refer to the following sample code.

Popup.xaml:

<ContentControl
x:Class="WpfApplication1.Popup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="300"
x:Name="popup">
<ContentControl.Template>
    <ControlTemplate TargetType="local:Popup">
        <Grid Background="#7f000000">
            <Grid Background="White" HorizontalAlignment="Center" VerticalAlignment="Center">
                <StackPanel Margin="20">
                    <TextBlock Text="{Binding Title, ElementName=popup}" FontSize="20" />
                    <ContentPresenter />
                </StackPanel>
            </Grid>
        </Grid>
    </ControlTemplate>
</ContentControl.Template>

Popup1.xaml.cs.

public partial class Popup : ContentControl
{
    public static DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(Popup));
    public string Title
    {
        get
        {
            return (string)GetValue(TitleProperty);
        }
        set
        {
            SetValue(TitleProperty, value);
        }
    }

    public Popup()
    {
        InitializeComponent();
    }
}

}

Window1.xaml:

<local:Popup Title="Title...">
     <TextBlock>Text...</TextBlock>
</local:Popup>
Share:
12,152
bytecode77
Author by

bytecode77

„What I cannot create, I do not understand.“ - Richard Feynman bytecode77.com

Updated on June 20, 2022

Comments

  • bytecode77
    bytecode77 almost 2 years

    I'm working on a modal dialog popup (I'm not sure about the exact UX term) that is displayed inline, inside of a control or window with darkened background.

    Visual example

    example

    What I tried is putting a <ContentPresenter /> inside the XAML of the popup and then just instantiate it like this:

    <local:Popup Grid.RowSpan="2">
        <TextBlock Text="Popup test..." />
    </local:Popup>
    

    However, the XAML replaces the entire Popup XAML instead of being placed where the ContentPresenter is.

    Q: How is the ContentPresenter here used properly?

    Popup.xaml

    <ContentControl
        x:Class="[...].Popup"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:[...]"
        mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="300">
        <Grid Background="#7f000000">
            <Grid Background="White" HorizontalAlignment="Center" VerticalAlignment="Center">
                <StackPanel Margin="20">
                    <TextBlock Text="{Binding Title, RelativeSource={RelativeSource AncestorType=UserControl}}" FontSize="20" />
                    <ContentPresenter />
                </StackPanel>
            </Grid>
        </Grid>
    </ContentControl>
    

    Popup.xaml.cs

    using System.Windows;
    
    namespace [...]
    {
        public partial class Popup : ContentControlBase
        {
            public static DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(Popup));
            public string Title
            {
                get
                {
                    return (string)GetValue(TitleProperty);
                }
                set
                {
                    SetValue(TitleProperty, value);
                }
            }
    
            public Popup()
            {
                InitializeComponent();
            }
        }
    }
    
  • bytecode77
    bytecode77 over 7 years
    The <ContentControl.Template> did all the trick. Thank you! +1