10

I am trying to display a dialog that allows the user to type a location, just like in the "add places" function of the Weather App on Windows 8.

Windows.UI.Popups namespace does not have an appropriate control. It has the MessageDialog, but I don't think it can be customised to include a textbox in it.

Would I need to use Windows.UI.XAML.Controls.Primitives.Popup control by any chance?

The input dialog in Weather App on Windows 8

Mani
  • 307
  • 1
  • 4
  • 8
  • 1
    Create a translucent gray div that covers the screen, then put a solid gray div on top of it. Inside the solid gray div, put your controls. – Raymond Chen Jul 21 '12 at 16:47
  • 1
    @RaymondChen, this question is about xaml/c# apps. You cannot mix html markup to xaml. – KyleMit Aug 11 '13 at 19:36
  • @KyleMit s/div/panel/g. I've done something similar to this when porting a js/html app to c#/xaml. – Raymond Chen Aug 11 '13 at 22:09

3 Answers3

12

There is no out of box control beyond Popup to handle this style of UI, the Callisto library uses this control quite a bit so it has a lot of good examples of it's usage.

Edit: In fact now the Callisto library has the CustomDialog control to help you do exactly this.

Nigel Sampson
  • 10,549
  • 1
  • 28
  • 31
6

Yes, you can use the Popup control, but you need to set the Child property to a content control which covers the full App window AND resizes when the window size is changed. It is not hard to create your own.

Create a Templated Control based on a ContentControl:

public sealed class PopoverView : ContentControl
{
    public PopoverView()
    {
        this.DefaultStyleKey = typeof(PopoverView);
        Loaded += OnLoaded;
        Unloaded += OnUnloaded;
    }

    /// <summary>
    /// Measure the size of this control: make it cover the full App window
    /// </summary>
    protected override Size MeasureOverride(Size availableSize)
    {
        Rect bounds = Window.Current.Bounds;
        availableSize = new Size(bounds.Width, bounds.Height);
        base.MeasureOverride(availableSize);
        return availableSize;
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        Window.Current.SizeChanged += OnSizeChanged;
    }

    private void OnSizeChanged(object sender, WindowSizeChangedEventArgs e)
    {
        InvalidateMeasure();
    }

    private void OnUnloaded(object sender, RoutedEventArgs e)
    {
        Window.Current.SizeChanged -= OnSizeChanged;
    }
}

Add this code to the Generic.xaml:

<SolidColorBrush x:Key="PopoverViewBackgroundThemeBrush">White</SolidColorBrush>
<!-- Semi-transparant black brush to cover the background: -->
<SolidColorBrush x:Key="PopoverViewOverlayThemeBrush">#80000000</SolidColorBrush>

<Style TargetType="local:PopoverView">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:PopoverView">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <Border Grid.Row="0" Background="{StaticResource PopoverViewOverlayThemeBrush}" />
                    <Border Grid.Row="1" Child="{TemplateBinding Content}" Background="{StaticResource PopoverViewBackgroundThemeBrush}" />
                    <Border Grid.Row="2" Background="{StaticResource PopoverViewOverlayThemeBrush}" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Now you can create a UserControl with the PopoverView as content. Example:

<UserControl
    x:Class="PopoverCustomControlTest.MyUserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PopoverCustomControlTest"
    xmlns:custom="using:MyCustomControls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <custom:PopoverView>
        <!-- Create your own dialog here instead of this simple button -->
        <Button Content="Close PopoverView"
                Click="Button_Click_1"
                Background="Black"
                HorizontalAlignment="Center"
                Margin="40" />
    </custom:PopoverView>

</UserControl>
public sealed partial class MyUserControl1 : UserControl
{
    private Popup popup;

    public MyUserControl1(Popup popup)
    {
        if (popup == null) throw new ArgumentNullException("popup");
        this.popup = popup;
        this.InitializeComponent();
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        this.popup.IsOpen = false;
    }
}

And show it when you need it:

Popup popup = new Popup();
popup.Child = new MyUserControl1(popup);
popup.IsOpen = true;
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Marcel Wolterbeek
  • 3,367
  • 36
  • 48
  • I couldn't make this work. I get an error in Generic.xaml that local:PopoverView cannot be found in the namespace. – mostruash Jan 18 '13 at 15:11
  • @mostruash: The example assumes that the PopoverView class is in the namespace specified at the top of your Generic.xaml file: xmlns:local="using:NamespaceWithPopoverView". If the PopoverView class is in another namespace, ADD that namespace at the top of your Generic.xaml file AND change the prefix for the PopoverView class (like xmlns:custom= in MyUserControl1). Example: if you specify xmlns:test1="using:NamespaceWithPopoverView", then use test1:PopoverView instead of local:PopoverView. – Marcel Wolterbeek Jan 20 '13 at 13:01
  • PopoverView class was in the main namespace (e.g. MyNamespace) of my project, moreover xmlns:local was already defined in Generic.xaml (xmlns:local="using:MyNamespace) so I didn't need to. The weird thing was IntelliSense would display none of the classes in MyNamespace. Maybe it was a bug in VS2012 and I needed to restart. – mostruash Jan 21 '13 at 10:31
2

You can't mix and match the XAML Controls with the html application experience.

You can either construct your own dialog control with all that it entails (focus is hard!), or I would recommend using the WinJS.UI.Flyout and related controls. Here are some guidelines: http://msdn.microsoft.com/en-us/library/windows/apps/hh465341.aspx

You should be able to style it as you see fit.

Dominic Hopton
  • 7,262
  • 1
  • 22
  • 29