Reputation: 2771
Hello I have an issue with positioning a popup, in a WP8 app.
My code is that I have instantiated a popup, where the child is a usercontrol, like:
Popup CenterPopup = new Popup();
LayoutRoot.Children.Add(CenterPopup);
CenterPopup = new UsercontrolElement();
This code would make my UsercontrolElement
appear precisely in the middle, as it looks in the design view for the xaml code. The problem is that my UsercontrolElement
is a waiting screen that I want to be visible during a page navigation in the back. This is not possible when the Popup is added to the LayoutRoot.
If I instead make the popup visible and specify size and what not, the positioning is extremely hard, and I have to handle LandscapeOrientation in usercode by trial and error for CompositTransform.
I was therefore wondering if you could use the above code but instead of adding the element to LayoutRoot, you would at it to something that is not only a root of the page such that the popup continues to have its intended position. I have illustrated the issue below:
This means it is possible to accomplish inserting the popup from the code behind. But it is independent of the page. Therefore one has to define the rotation for each pageOrientation, and fit the rotation for every popup, which is not a nice solution. Edit
Okay so I tried to play around with the VisualTreehelper and did this:
Border outBorder = (Border)VisualTreeHelper.GetChild(Application.Current.RootVisual, 0);
ContentPresenter outContent = (ContentPresenter)VisualTreeHelper.GetChild(outBorder, 0);
outContent.Content = popup;
This gives the Desired effect from the image above. However, the secondscreen is never loaded. That is I have a loadedEvent that is never fired.
The solution would therefore might be to go one step up with the VisualTreeHelper, but as far as I know this is the page? And then I would be back to the same issue.
Anyone has an idea`?
Upvotes: 3
Views: 319
Reputation: 6590
I am not sure but try something like this.
var activePage = (PhoneApplicationPage) RootFrame.Content;
var pageContent = (Grid) activePage.Content;
UsercontrolElement childpopup = new UsercontrolElement();
Grid.SetRowSpan(childpopup , pageContent.RowDefinitions.Count);
pageContent.Children.Add(childpopup );
Upvotes: 1
Reputation: 39006
If I understand your question correctly, this can be achieved by customizing the PhoneApplicationFrame
's style of your phone application.
Inside the ContentTemplate
of the default style of PhoneApplicationFrame
, you will find a ContentPresenter
that hosts the pages of your app. Here you simply need to create another container that hosts your usercontrol on top of this ConcentPresenter
. Also you don't have to use a Popup
here to host your usercontrol, I'd simply wrap it within another Grid
. The reason for this is that Popup
has some serious performance issues in WP8. If you have the xaml code placed below the ContentPresenter
, it will always be on top of the pages.
<Style TargetType="phone:PhoneApplicationFrame">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}" />
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeNormal}" />
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Padding" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:PhoneApplicationFrame">
<Border x:Name="ClientArea" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" d:DesignWidth="480" d:DesignHeight="800" Loaded="ClientArea_Loaded">
<Border.Resources>
<Storyboard x:Name="ShowTransitionPopup" AutoReverse="True">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="TransitionPopup">
<EasingDoubleKeyFrame KeyTime="0" Value="-124"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="TransitionPopup">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Border.Resources>
<Grid>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" />
<Grid x:Name="TransitionPopup" Canvas.ZIndex="9999" Background="{StaticResource PhoneAccentBrush}" Height="240" Width="360" Opacity="0" RenderTransformOrigin="0.5,0.5" >
<!-- put your control here -->
<Grid.RenderTransform>
<CompositeTransform/>
</Grid.RenderTransform>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In the above example, I've created a little animation called ShowTransitionPopup
and it is called when the pages are navigating (OnNavigatingFrom
). I didn't specifically write code to position the container since there's just one container you need to handle, it should be quite easy to implement.
I've attached a working sample here for your reference. By pressing the navigation button on the bottom of the page, you will see an animated rectangle fade in and out on the UI.
Hope this helps!
Upvotes: 3
Reputation: 2275
This is not possible in Windows Phone 8. It would be possible in WinRT 8.1. The reason is that you need to go up further than the control where the navigation occurs, and that is the PhoneApplicationFrame for Windows Phone 8. Per the documentation:
Frames
A frame integrates with the Windows Phone look and feel so that it appears like any other application. Only a single frame is available to the application with no exceptions. A frame includes the following characteristics:
•Exposes properties from a hosted page such as screen orientation
•Exposes a client area where pages are rendered
•Exposes a NavigationService that facilitates navigating between pages
•Reserves space for the status bar and Application Bar
If you could go above the PhoneApplicationFrame and host multiple PhoneApplicationFrames, you could put some XAML into it that would allow you to interact with multiple Frames and place something in between the page navigations. However, you can't in Silverlight 8.0. In face, the RootFrame does not have a parent, so you can't even make any other control it's sibling.
If you're willing to build your own navigation service (which I don't recommend), you can simulate this within a single page using UserControls.
Upvotes: 1