SilverLight 4 - How to have Buttons to switch between view in grid - silverlight-4.0

I‘m trying to create a page with Silver Light 4, that is similar in functionality to the main page at the Silver Light Showcase website (http://www.silverlight.net/showcase/).
Essentially I want to have buttons that change the view of the data in a Grid. One view might have just an image, another might have a smaller image with a smattering of data, and the third would be all the details.
I wondering if anyone has a recommendation of how to achieve this?

I would place a Border control inside of the Grid. Then on button click change the border.Child to the new view. You could define each view in a seperate UserControl xaml file.
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border x:Name="contentFrame" />
<Button x:Name="changeViewButton" click="click_event" Grid.Row="1" Height="22" Width="150" />
</Grid>
// code behind
protected void click_event(object s, EventArgs e)
{
View1 view1 = new View1();
// add some code to decide which view to show, possible hold onto the view in memory etc.
this.ContentFrame.Child = view1;
}

Related

How to make my contentview in the center of the screen, above my grid?

Right now my ContentView (acts like a pop up window) stacks on top of my grid, see code below:
<StackLayout>
<ContentView>...</>
<StackLayout>
<Grid>...</>
</StackLayout>
</StackLayout>
The grid is a form, so when I press a button in my form, I want a new pop up window (the contentview) to be above the grid, in the center of the screen. The idea is that you can still see some of the form behind the contentview.
How do I put contentview in the front and not stacked on top of my grid?
Here's my contentview
<ContentView x:Name="popupAddDetails" AbsoluteLayout.LayoutBounds="0,0,1,1"
VerticalOptions="Center" HorizontalOptions="Center">
PS: I'm new to this environment and still learning. Thankful for any help
I tried to make a stacklayout above my first stacklayout with my grid in it and then set vertical and horizontal attributes in my contentview to center. But it just stacked upon my inner stacklayout.
You could simply use Xamarin Community Toolkit Popup to make it.
First of all, add a new Nuget named Xamarin.CommunityToolkit to your project.
Then, create a popup page which will be shown when you click a button. This is much similar to creating a ContentPage.
<?xml version="1.0" encoding="UTF-8" ?>
<xct:Popup
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ContentDemo.CommunityPopupPage"
xmlns:xct="clr- namespace:Xamarin.CommunityToolkit.UI.Views;assembly=Xamarin.CommunityToolkit">
<StackLayout WidthRequest="200" HeightRequest="200"BackgroundColor="Red"HorizontalOptions="Center" VerticalOptions="Center">
<Label Text="hello"/>
</StackLayout>
</xct:Popup>
The .cs may be something like this:
using Xamarin.CommunityToolkit.UI.Views;
namespace ContentDemo
{
public partial class CommunityPopupPage : Popup
{
public CommunityPopupPage()
{
this.Size = new Size(300, 300); //you could change the size of the popup
InitializeComponent();
}
}
}
Finally, you may want to open this popup page via a button clicked event. Don't forget to add this line:
using Xamarin.CommunityToolkit.Extensions;
void Button_Clicked(System.Object sender, System.EventArgs e)
{
App.Current.MainPage.Navigation.ShowPopup(new CommunityPopupPage());
}
I created this demo and it worked well. You could refer to Xamarin Community Toolkit Popup and Getting Started with the Xamarin Community Toolkit for more information.
====================update =====
2.Using outer layout as a Grid instead of a StackLayout might be an alternative. Just something like this:
<Grid x:Name="outerGrid" VerticalOptions="Center" > //this grid includes the grid and the contentview to be shown
<Grid x:Name="innerGrid">
<Grid.RowDefinitions>
...
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
</Grid>
<ContentView>
... // design the content
<ContentView />
</Grid>
In this way, the ContentView will be placed above the innerGrid. But I prefer using a popup page.
Hope it works for you.

Issues with child page's display when using Frames

Problem
This is the layout of my main pane:
<Page
x:Class="Communities.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Communities"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Loaded="Page_Loaded" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="48" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
...
<SplitView Grid.Row="1" Name="hamburgerMenu" OpenPaneLength="200" PaneBackground="#F02A2A2A">
<SplitView.Pane>
<ListView ItemsSource="{Binding}" IsItemClickEnabled="True" ItemClick="HamburgerItemClick">
... </ListView>
</SplitView.Pane>
<Frame Name="frame" />
</SplitView>
<Grid Grid.RowSpan="3" Name="popupArea" />
</Grid>
</Page>
the frame is where I load all my pages, so that the layout is always consistant.
Now, in most of my child pages I have defined AppBar control and attached it to the BottomAppBar property of that child page:
PostView.xaml
...
<Page.BottomAppBar>
<CommandBar>
<AppBarButton Label="Back" Icon="Back" Click="TryGoBack" />
<AppBarButton Label="Refresh" Icon="Refresh" Click="TryRefreshComments" />
<AppBarButton Label="Go to Community" Icon="Go" Click="TryOpenCommunity" />
</CommandBar>
</Page.BottomAppBar>
...
Here's where the trouble starts. It works fine on PC, as the layout is mostly static on desktop. There are no software keyboards required most of the time etc. On mobile it's more problematic: Screenshots
My thoughts
It seems like the frame that is used to display the child page is causing all sorts of problems. When the AppBar is defined in the main page it positions correctly.
I'd like to avoid the keyboard covering the textbox as well as the AppBar but I don't want to get rid of the frame control. I'd also prefer it if the page got "squished" when the keyboard shows up, instead of getting pushed upwards, but I'm not sure how to display the keyboard on the frame level, instead of the entire MainPage, default level.
What would be the best way to solve this situation?
Cheers!
As you know, if we set the Page.BottomAppBar in the root of the Page, there is no issue with Touch keyboard. It seems it is the best way to add the Page.BottomAppBar.
If you want to add the Page.BottomAppBar in the other page in the Frame, you should be able to customize your UI. The UWP provides similar behavior on the appearance of the touch keyboard by handling the Showing and Hiding events exposed by the InputPane object.
We can use the InputPaneVisibilityEventArgs.OccludedRect to get the region of the application's window that the input pane is covering.
For example:
public PostView()
{
this.InitializeComponent();
InputPane.GetForCurrentView().Showing += PostView_Showing;
InputPane.GetForCurrentView().Hiding += PostView_Hiding;
}
private void PostView_Hiding(InputPane sender, InputPaneVisibilityEventArgs args)
{
MyTextBox.Margin = new Thickness(0, args.OccludedRect.Height, 0, 0);
}
private void PostView_Showing(InputPane sender, InputPaneVisibilityEventArgs args)
{
MyTextBox.Margin = new Thickness(0, 0, 0, args.OccludedRect.Height);
}

UWP Page Preload ( Is it possible to preload the contents of a page )

I'm working on a Windows 10 app. and i created map in my second page.. but it is too slow.. Is it possible to preload the contents of a page before displaying it to the user so that the transition from page x to page y is smooth?
Is not possible, all pages in uwp apps will be rendered when you navigated to some page.
But you can prepare the data before to navigate to your second page maybe you can save this data in the local storage and load the data in the method OnNavigatedTo in your second page it would be better.
The easiest option is probably to not make it a page at all; instead, have the map on the page you are starting from, but have its Opacity be zero. Then when you want to show it, set the Opacity to one. This if course means you pay the cost of loading the map even if the user never wants to view it, but it makes viewing instant.
Sample XAML:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Content="go to map" Click="GoToMap" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Grid x:Name="mapLayer" xmlns:maps="using:Windows.UI.Xaml.Controls.Maps" Opacity="0" IsHitTestVisible="False">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<maps:MapControl />
<Button Content="back" Click="HideMap" HorizontalAlignment="Center" Grid.Row="1"/>
</Grid>
</Grid>
And matching code:
private void GoToMap(object sender, RoutedEventArgs e)
{
mapLayer.Opacity = 1;
mapLayer.IsHitTestVisible = true;
}
private void HideMap(object sender, RoutedEventArgs e)
{
mapLayer.Opacity = 0;
mapLayer.IsHitTestVisible = false;
}

Changing the size of SplitView.Pane

The basic hamburger menu using SplitView found in many examples is cool but I like the way Microsoft implemented it in some of their apps in Windows 10 such as News and Sports. The way they implemented it is when the SplitView.Pane is open, its height is not the same as the root frame's height. In other word, the Pane's height and Content's height is not the same. The benefit of this style is that full content of the pageheader of the SplitView.Content is visible. Can somebody help me out on how to achieve that effect since I am new to xaml. I hope my question is pretty clear to understand.
Thanks,
AB
On the official "sport"/"news" page, there are several elements: toggle button, SplitView and etc. In the SplitView, there are also several sub-items, such as panel and frame. There are lots of approaches to help you to get your own desired effect: you can use layout panel, such as StackPanel or Grid, to arrange those UI elements on the page; you can modify the splitview's default template; and you can also just customize frame and panel' height by setting their related properties, such as: height or Margin. For more instructions of UWP design please go here.
Below is a simple example by using Grid layout and adjusting "margin" property of splitview's frame. In this example, I put the toggled button and a back button on the page header (you can change the back button to a navigation bar later). Then adjust the "margin" property of the frame, so that it doesn't has the same height as the panel. You can get a complete sample of SplitView here.
<!-- Put the whole page content in a grid of 2*2 -->
<Grid>
<Grid.RowDefinitions >
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button x:Name="BackButton"
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Center"
TabIndex="2"
IsEnabled="{Binding AppFrame.CanGoBack, ElementName=Root}"
Width="{Binding ItemsPanelRoot.Width, ElementName=NavMenuList}"
Click="BackButton_Click"/>
<!-- Top-level navigation menu + app content
and put the SplitView in another row to leave space for page header -->
<SplitView x:Name="RootSplitView"
DisplayMode="Inline"
OpenPaneLength="256"
IsTabStop="False" Grid.Row="1" Grid.ColumnSpan="2">
<SplitView.Pane >
<!-- A custom ListView to display the items in the pane. The automation Name is set in the ContainerContentChanging event. -->
<controls:NavMenuListView x:Name="NavMenuList"
TabIndex="3"
ContainerContentChanging="NavMenuItemContainerContentChanging"
ItemContainerStyle="{StaticResource NavMenuItemContainerStyle}"
ItemTemplate="{StaticResource NavMenuItemTemplate}"
ItemInvoked="NavMenuList_ItemInvoked">
</controls:NavMenuListView>
</SplitView.Pane>
<!-- Set Frame's margin property to differ from panel -->
<!-- OnNavigatingToPage we synchronize the selected item in the nav menu with the current page.
OnNavigatedToPage we move keyboard focus to the first item on the page after it's loaded. -->
<Frame x:Name="frame"
Navigating="OnNavigatingToPage"
Navigated="OnNavigatedToPage"
Margin="0,100,0,0" >
<Frame.ContentTransitions>
<TransitionCollection>
<NavigationThemeTransition>
<NavigationThemeTransition.DefaultNavigationTransitionInfo>
<EntranceNavigationTransitionInfo/>
</NavigationThemeTransition.DefaultNavigationTransitionInfo>
</NavigationThemeTransition>
</TransitionCollection>
</Frame.ContentTransitions>
</Frame>
</SplitView>
<!-- Declared last to have it rendered above everything else, but it needs to be the first item in the tab sequence. -->
<ToggleButton x:Name="TogglePaneButton"
TabIndex="1"
Style="{StaticResource SplitViewTogglePaneButtonStyle}"
IsChecked="{Binding IsPaneOpen, ElementName=RootSplitView, Mode=TwoWay}"
Unchecked="TogglePaneButton_Checked"
AutomationProperties.Name="Menu"
ToolTipService.ToolTip="Menu" Grid.Row="0" Grid.Column="0" />
</Grid>

Windows Phone items scroll issue while SIP keyboard appear

I'm facing two issues with the code following while I'm making a simple chat app.
The code shows a textblock at the top of the page and two textbox stack at the bottom. Plus a listbox which will be auto height to fill the remaining gap.
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle Height="1" Fill="White" VerticalAlignment="Top"/>
<TextBlock Text="Hello World!" Grid.Row="0" FontSize="36"/>
<Listbox Grid.Row="1"/>
<TextBox Grid.Row="2"/>
<TextBox Grid.Row="3"/>
</Grid>
When I click on one of the top textboxes, the SIP keyboard becomes visible and all content in the page is pushed up. The main issue here is that the top textblock disappears and hides over the top. How can I keep it on top and not moving while the SIP keyboard is viewed?
When the most bottom textbox has focus, the SIP keyboard appears and pushes all content up. In this case, the keyboard will just fit and be sticky to that textbox. However, when the other textbox has focus, the keyboard will make a gap between them. How can I make the keyboard behave as it does when the most bottom one is focused?
When the keyboard pops and unpops, a TranslateTransform runs on the PhoneApplicationFrame, translating the whole screen up and down.
Based on this article, you should be able to get the value of the translation. As you can observe an animation moves the Y property from zero to a specific negative value (based on the control you took focus on).
Option 1: I have not been able to write a descent way of handling this value but you should be able to resize your controls to fit in what's left of the screen.
Option 2.0 (bad): You can cancel or remove this animation. The keyboard will be on top of the screen without any movement. Your turn now to move/resize your controls to fit the remaining space.
public MainPage()
{
this.InitializeComponent();
PhoneApplicationFrame frame = (App.Current as App).RootFrame;
var group = (frame.RenderTransform as TransformGroup);
group.Children.RemoveAt(0); // remove translate transform
}
Option 2.1: There's an issue with 2.0: removing the transform will prevent you from being notified about the keyboard. Setting up a reverse animation on your page's child when the Y property changes will "kind of cancel" the original translation.
<Grid x:Name="LayoutRoot" Background="Transparent" VerticalAlignment="Stretch">
<Grid.RenderTransform>
<TransformGroup>
<TranslateTransform />
</TransformGroup>
</Grid.RenderTransform>
static void OnRootFrameTransformChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
// ... edit from the blog article ...
MainPage page = source as MainPage;
page.lb.Items.Add(newvalue);
var oppositeTransform = (TranslateTransform)((TransformGroup)page.RenderTransform).Children[0];
if (newvalue < 0.0)
{
page.IsSipVisibleGuess.IsChecked = true;
oppositeTransform.Y = -newvalue;
}
else if (newvalue == 0.0)
{
page.IsSipVisibleGuess.IsChecked = false;
oppositeTransform.Y = 0;
}
I'm sorry none of these options will magically solve the problem but it may help you code what fits best for your app.
If you find a better solution out of this, please post it as an answer.