I have a Windows universal UWP app that I am using Pivot on to give me the ability to swipe from page to page for navigation. Let's say I have three UI pages (page1, page2 and page3), I then have three PivotItems, one for each. The question is, inside of the PivotItem, I currently have a Frame in each and am using the Frame to show the UI page. This is working, however, this seems redundant because as I understand it, a Frame is used to dynamically show content such as a UI. It seems that you would have EITHER buttons or links for the tabs in a grid and then use one frame to rotate the UI views depending on which button is clicked OR you would use pivot, which I am doing. Main reason I chose pivot, I am targeting mobile and I do want to be able to swipe from page to page.
So, what I don't know is, when using pivot, what do I put in each PivotItem? Is a frame on each correct? Or should I use some other item like UIElement?
Thanks!
What I want to know specifically is instead of stuffing controls directly in the PivotItem, how do I just have each PivotItem reference and use my other pages?
Pivot is a ItemsControl.so it can contain a collection of items of any type, including the Page. You can use pages in PivotItem like below:
<Page
x:Class="ProjectName.MainPage"
xmlns:local="using:ProjectName"
...
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Pivot x:Name="rootPivot" Title="Pivot Title">
<PivotItem Header="Pivot Item 1">
<!--reference the page with local:PageName-->
<local:PageOne></local:PageOne>
</PivotItem>
<PivotItem Header="Pivot Item 2">
<local:PageTwo></local:PageTwo>
</PivotItem>
<PivotItem Header="Pivot Item 3">
<local:PageThree></local:PageThree>
</PivotItem>
</Pivot>
</Grid>
Related
I would like to know if there's a way to implement a responsive Master/Detail page using only one. What I want is something exactly like the Project here:
https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/XamlMasterDetail
Except for the detail that instead of using two pages and navigating from one to another I would only use one page.
Is there a way to do it? If so, could you link me a working example?
Except for the detail that instead of using two pages and navigating from one to another I would only use one page.
After going through the project, I found it implemented a responsive master/detail experience based on the size of the screen. When the app view is sufficiently wide, the master list and detail view should appear side by side in the same app page. However, on smaller screen sizes, the two pieces of UI should appear on different pages, allowing the user to navigate between them. From my point of view, I think this is a good solution for implementing a responsive master/detail experience.
Is there a way to do it? If so, could you link me a working example?
The project already shows how to implement responsive Master/Detail in UWP using only one page, but it implements more and that makes it a little complex to understand. So I make a simple example which directly shows how to implement responsive Master/Detail in UWP using only one page.
Following is the main steps:
First, create a ListView to show master information in xaml page:
<!--Master VIEW-->
<ListView x:Name="ItemListView" Margin="0,0,0,8">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Left" Margin="10,8,0,0">
<TextBlock Text="{Binding Title}" FontSize="25" Width="400" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Second, specify the details view that shows the details item related to the selection on the master list in the same xaml page:
<!--DETAILS VIEW-->
<StackPanel Grid.Column="1" x:Name="ContentPanelDetail" Margin="10,0,0,0" DataContext="{Binding SelectedItem, ElementName=ItemListView}">
<TextBlock Text="{Binding Title}" MaxHeight="80" FontSize="30" HorizontalAlignment="Left" Margin="0" />
<TextBlock x:Name="DetailTextBlock" FontSize="35" Text="{Binding Content}" HorizontalAlignment="Left" Margin="0,18,40,0" Width="500" Height="Auto" TextWrapping="Wrap" />
</StackPanel>
Then, set the ItemsSource for the ListView in code behind:
public MainPage()
{
this.InitializeComponent();
//set the ItemsSource for the ListView
ItemDetails messageData = new ItemDetails();
ItemListView.ItemsSource = messageData.Collection;
ItemListView.SelectedIndex = 0;
}
Last but not least, put Master View and Details View into a SplitView and use VisualStateManager to make it more responsive.
Here is the simple example and the output for your reference.
To implement Master/Detail pattern on your page, you don't have to do it yourself. Instead you can use MasterDetailsView control from UWP Community Toolkit, it does a lot work for you + it is well documented.
Note: For details section of the control, do not set background to null (NoSelectionContent will be visible).
How can I let a user of a Windows Universal App swipe from one page to another? (I thought this would be easy to find, but searching hasn’t uncovered the answer.)
And if this is possible within one page - that's fine too. (To swipe one grid out and another in.)
Pivot control behaves like you discribed.
See guidelines for tabs and pivots.
Example:
<Page x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Pivot>
<PivotItem Header="Item 1" Background="Black" />
<PivotItem Header="Item 2" Background="Red" />
<PivotItem Header="Item 3" Background="Blue" />
</Pivot>
</Grid>
You can use GestureRecognizer and manipulate what you wanna do. Create animation for the FX.
I want to say use a FlipView control, but that could be dangerous if your views are too complex. FlipView will keep your pages rendered and ready to be flipped to at all times. I think you can try to implement your own thing to keep memory usage low. Maybe use a GestureRecognizer so that you have control over where the user can swipe and only render what you need and discard anything obsolete or off the screen.
Pivot will also create this effect, but the difference is that it must completely slide one element off the screen and then slide the next one in. It keeps from having two or three views rendered at once, which is good for memory. However, you won't be able to see both pages sliding in/out at the same time.
Try them both, see which is best for you.
I have something similiar to what you're asking:
How to "swipe" from one page to another:
On page 1 (The page where you will swipe FROM)
Make a grid, and put these values in:
XAML:
<Grid Padding="15,15,15,15"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
ManipulationMode="TranslateX,TranslateInertia,System"
ManipulationDelta="SwipeablePage_ManipulationDelta"
ManipulationCompleted="SwipeablePage_ManipulationCompleted">
Code Behind:
private bool _isSwiped;
private void SwipeablePage_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (e.IsInertial && !_isSwiped)
{
var swipedDistance = e.Cumulative.Translation.X;
if (Math.Abs(swipedDistance) <= 2) return;
if (swipedDistance > 0)
{
// go to next page
this.Frame.Navigate(typeof(Page2));
}
else
{
// do nothing
}
_isSwiped = true;
}
}
I have a problem with Pivot control. How can I insert xaml page with content to Pivot item? Is it even possible?
When I’m storing everything in one file it’s really hard to take control over my own application layout.
I want something like this:
on main page should be pivot control with items.
content of those items should be in separated xaml files (there is no dependency between pages)
Add correct namespace to Page:
xmlns:view="clr-namespace:YourApp.Controls"
and in Pivot:
<Pivot>
<PivotItem Name="first">
<view:FirstUserControl DataContext="{Binding YourViewModel}"/>
</PivotItem>
</Pivot>
And in view namespace you need to create a User Control. The link is about WPF but in WP7 there is the same system.
Also, you can create Custom Control from PivotItem.
I have a TabControl with TextBox controls in the ContentTemplate. When I type some text in one tab and switch to another tab, the Undo history in the original tab is gone when I go back.
Another problem that comes up is any text that was selected is deselected and the caret moves to the beginning of the TextBox.
If I make a window with just hardcoded TabItem controls, the undo history is preserved. The issue has something to do with my binding or templates.
Here is my XAML for the main window
<Window x:Class="TabbedTextAreaTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Command="{Binding AddNewTab}">Add Tab</Button>
<TabControl ItemsSource="{Binding Tabs}" Grid.Row="1">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<TextBox Text="{Binding Content, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</Window>
Is there a way to preserve the undo/redo history and selected text when switching tabs without manually catching those commands?
When you use a TabControl which gets its tabs via databinding on ItemsSource, WPF doesn't keep the visual tree for each item around as you switch. Thus, when you switch from tab 1 to tab 2, then back to tab 1, the controls on tab 1 are not actually the same control instances which you saw on tab 1 the first time.
There are a number of ways around to deal with this - TabControls which have explicit TabItem instances do keep their visual trees when you switch tabs, so probably the easiest way to do it is to wrap your collection of tab items in something which makes TabItems for them.
Unfortunately right now I can't find a link to an example of how to do this. There are references to articles elsewhere on SO, but they all seem to point to pages which no longer exist, and I don't have time to dig any deeper.
The reason is simple. If you think the both operation you complain about are strictly UI operations: Undo: user editing on the UI control, selection: selection of the text on UI control.
When you swicth Tab to another and go back, what happens in WPF is that all controls are rebinded to there data (ModelView normally, or just Model) again, as if you was showing them for the first time. So they loose their UI appearance attributes.
To manage that correctly in Tab environment in WPF you need to manage Undo/Redo stack by your own.
Good luck.
So I have a Panorama control and the PanoramaItems are programmatically added to the control using the following template.
<UserControl>
<Grid x:Name="LayoutRoot">
<controls:PanoramaItem Name="sitePanoramaItem" Header="{Binding Name}">
<Controls:DockPanel VerticalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0" Controls:DockPanel.Dock="Top">
<Image Source="../Images/action.png" Width="64" />
<TextBlock Text="{Binding Stats, Mode=TwoWay}" FontSize="45" Margin="15,0,0,0" />
</StackPanel>
<Grid x:Name="graphCanvas" HorizontalAlignment="Stretch" Margin="10,10,10,10"> </Grid>
</Controls:DockPanel>
</controls:PanoramaItem>
</Grid>
</UserControl>
When I click on graphCanvas what I'd like to do is sorta pop the graphCanvas out and display that fullscreen then when I click again restore it to where it was. I've been all over this site and Google and can't find anything similar to what I'm looking for.
I would still like to maintain the Panorama control functionality so that the graphCanvas is still the only one visible but you can cycle through them. Currently I have it sorta working in that I remove the Grid from the DockPanel and put it directly in the LayoutRoot while making the sitePanoramaItem collapsed. However, it's not fullscreen as the Panorama name is still visible (I guess I could hide that as well...) When I put the graphCanvas back int he DockPanel the size of the canvas is all screwed up.
I was hoping there was a simpler way.
Is it even possible?
It is possible to create the UI you describe but it's not going to be simple. You're on the right track with removing it in code and adding it the LayoutRoot and making the Panorama hidden. However you would have to code the scrolling behavior yourself and that is going to be quite tricky - especially making it feel the way to panorama does.
One trick you could try is actually layer a PivotControl on top of your Panorama and have it be collapsed by default. Also edit it's template to remove all default content eg: remove the header control, set margins to 0, etc). Then when you want to go full screen you can remove all the graphCanvases from the Panorama items and and add them to new PivotItems in the PivotControl. Then hide the Panorama and show the Pivot. This will give you scrolling capability for free and the illusion of full screen.
Having said all that I'm not sure I would recommend this. The more common approach would be to simply be to navigate to another page when the user selects an item and handle the full screen aspects there (possibly using the Pivot control again for scrolling). And when you want to leave "fullscreen" mode simply navigate back to the first page. Handling Tombstoning of the fullscreen state will be much easier with this approach for one thing.
You can try making the graphCanvas a Page and putting it in a different XAML. Then add a frame (name it InnerFrame for example) in the same place where you have the graphCanvas right now and navigate to that page with InnerFrame. When the frame is clicked, you navigate with the RootFrame of the app to your graphCanvas page. When you decide to close it, just navigate back with the RootFrame.
Hope it's clear enough :)
Edit:
Navigation in WP7 works very similar as the standard navigation in Silverlight 4, but it's a bit more restrictive. Just throw a PhoneApplicationFrame in your XAML like this:
<phone:PhoneApplicationFrame x:Name="Frame" />
This is basically the same as a Silverlight frame. All the pages you create inherit from PhoneApplicationPage by default, so they can be showed in a frame without any changes.
Your whole application actually runs on a PhoneApplicationFrame. If you take a look at your App class you will see this:
public PhoneApplicationFrame RootFrame { get; private set; }
Here's the MSDN documentation for the navigation system on WP7