Best practise to navigation in windows phone 8.1[RT] xaml - c#

Hello I am working with windows phone 8.1[RT] application , I simply navigate page only . but I found new option we can use Frame in xaml also like this
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Background="White">
</Border>
<Button Content="next" Click="Button_Click" Background="Black" />
<Grid Grid.Row="1">
<Frame x:Name="Page1Frame" Background="Black" >
<StackPanel>
<Rectangle Height="100" Width="100" Fill="Red" Margin="5" />
<Rectangle Height="100" Width="100" Fill="Red" Margin="5" />
<Rectangle Height="100" Width="100" Fill="Red" Margin="5" />
<Rectangle Height="100" Width="100" Fill="Red" Margin="5" />
</StackPanel>
</Frame>
</Grid>
</Grid>
and navigate this frame like this
private void Button_Click(object sender, RoutedEventArgs e)
{
Page1Frame.Navigate(typeof(BlankPage1));
}
in this example my 120 height grid remain same and just navigate the frame .
I just want to know which is best practice to use ?
Thank you.

Page is page, Frame is frame, they are different.
Suppose your current page named MainPage, if you want to stay in MainPage and change the content of grid in root grid's row 1, you should use:
Page1Frame.Navigate(typeof(BlankPage1));
If you want to leave MainPage to go to another page, you should use:
var rootFrame = Window.Current.Content as Frame;
rootFrame.Navigate(typeof(BlankPage1));
and in this case, what you see is a blank page without 120 height grid remain.

Related

Hiding/Showing a UserControl WPF

I am building a WPF MVVM application.
What I have:
I have a ShellWindow which looks like this:
It is composed by 2 rows:
1: the hamburger menu (not important) with Height="*"
2: the console with Height="100"
The console is a UserControl:
<UserControl
//namespaces>
<Grid Name="LoggingGrid" Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Margin="{StaticResource SmallLeftMargin}">
<Button
x:Name="CollapseBtn"
Width="25"
Height="25"
Click="CollapseBtn_Click"
Content="▲">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="White" />
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
<StackPanel Margin="5,0,0,0" Orientation="Horizontal">
<Image
Height="25"
Source="/Images/console-icon.png"
Visibility="Visible" />
<Label
Content="Console"
FontSize="16"
Foreground="White" />
</StackPanel>
</TextBlock>
<Border Grid.Row="1">
<ListView
x:Name="LoggingList"
Margin="5"
Background="Black"
BorderThickness="0"
Foreground="White"
ItemsSource="{Binding Logs, UpdateSourceTrigger=PropertyChanged}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
</Border>
</Grid>
</UserControl>
I have omitted the non-important things.
What I want to do:
Whenever the user clicks on the button, the console should collapse and look something like this:
The arrow is also changed.
How can I implement this? What is the best approach using MVVM?
What I have tried:
I have tried using a button click event handler in the code behind - CollapseBtn_Click, just to see what will happen:
private void CollapseBtn_Click(object sender, System.Windows.RoutedEventArgs e)
{
LoggingGrid.Visibility = System.Windows.Visibility.Hidden;
}
Apparently it removes the user control and leaves a white background where it used to be.
Instead of setting the Visibility of the whole LoggingGrid to Hidden, you should set the Visibility of the LoggingList to Collapsed. (For the difference between Hidden and Collapsed, see here: Difference between Visibility.Collapsed and Visibility.Hidden).
Depending on your layout in the ShellWindow you probably have to adjust your row height configuration in the UserControl such that the collapsed LoggingGrid leads to a row with a height of zero.
Regarding MVVM the best approach would be to bind the Button to a bool property ConsoleVisible on your ViewModel such that clicking the button toggles the property between true and false. The styling of the button can be bound to the same property. For the LoggingList Visibility you could use a Binding with a BooleanToVisibilityConverter on the same property.

Checking specific radiobutton when navigate to page

In a windows 8.1 project i have a ListView that displays several items that look something like this:
I basically display agenda points, that can have 2 sub levels
if subpoint at first level has no subpoints itself it is a radiobutton, otherwise the subpoints it contains are radiobuttons.
the radiobutton points have this template.
<DataTemplate x:Key="WithSubTemplate2">
<Grid Width="280" Height="50" Margin="85,0,0,0" HorizontalAlignment="Right">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="5" />
</Grid.RowDefinitions>
<RadioButton GroupName="meetingFiles" Tag="{Binding}" Checked="RadioButton_Checked" Content="{Binding Name}" Style="{StaticResource RadioButtonStyle1}"></RadioButton>
<Ellipse Width="20" Height="20" Fill="#b3d0dd" HorizontalAlignment="Right" Margin="0,0,10,0"></Ellipse>
<TextBlock Text="{Binding AttachmentNumber}" HorizontalAlignment="Right" FontFamily="Segoe UI Regular" FontSize="16" Foreground="{StaticResource BrandBrush}" Margin="0, 14,15,0"></TextBlock>
<Grid x:Name="whiteLine" Grid.Row="1" Width="270" Height="1" Background="#80b0c6" HorizontalAlignment="Center" />
</Grid>
</DataTemplate>
When i check one of the radio buttons, i have a control that displays a pdf, and then when i want to edit that pdf it navigates to another page.
What i want is, when i go back to the previous page to have the RadioButton i checked earlier to be checked when the page opens.
Any way i can achieve this?
You can simply use:
this.NavigationCacheMode = NavigationCacheMode.Required;
That'll save current page status :).

Getting time of the freeze frame in WPF

I want to get a time of a freeze frame of a video which is paused by the pause button in WPF. I want to store time of that freeze frame and use it in the future. How do i get a perfect time of that specific frame? What type of variable i should use to store that time?
I'd use the Position property, which returns a TimeSpan:
XAML
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<MediaElement x:Name="MyMediaElement"
Grid.Row="0"
LoadedBehavior="Manual"
Source="SomeDrive:\SomeFolder\SomeMediaFile.mp4" />
<StackPanel Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<Button Width="50"
Height="50"
Click="PlayMedia"
Content="Play" />
<Button Width="50"
Height="50"
Click="PauseMedia"
Content="Pause" />
<TextBlock x:Name="MyTextBlock"
FontSize="30"
Text="0" />
</StackPanel>
</Grid>
Codebehind
private void PlayMedia(object sender, RoutedEventArgs e)
{
MyMediaElement.Play();
}
private void PauseMedia(object sender, RoutedEventArgs e)
{
MyMediaElement.Pause();
var currentTime = MyMediaElement.Position;
MyTextBlock.Text = currentTime.ToString();
}
I believe you are after the Clock property of the MediaElement.
See the documentation.
You can access the CurrentTime property. See more documentation.

How to solve this App bar display issue in windows phone 8 application?

I'm developing WP8 application . i need to add application bar in menu page.
with following code i add the app bar.
but button image hide when app bar code is present .
tell me where i made mistake . how to solve this?
Code For App Bar
public MainPage()
{
InitializeComponent();
BuildLocalizedApplicationBar();
}
private void BuildLocalizedApplicationBar()
{
ApplicationBar = new ApplicationBar();
ApplicationBarIconButton appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/appbar.add.rest.png", UriKind.Relative));
appBarButton.Text = AppResources.AppBarButtonText;
ApplicationBar.Buttons.Add(appBarButton);
ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarMenuItemText);
ApplicationBar.MenuItems.Add(appBarMenuItem);
}
XAML Code
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="10,0,14,0">
<Button x:Name="Stay" BorderThickness="0" Width="160" HorizontalAlignment="Left" Margin="0,128,0,427">
<Image Name="stayimg" Source="Assets/Images/Icons/stay_up.png" Stretch="Uniform" Height="139" Width="133"></Image>
</Button>
<Button x:Name="Eat" BorderThickness="0" Width="155" HorizontalAlignment="Left" Margin="165,128,0,427">
<Image Name="Eatimg" Source="Assets/Images/Icons/eat_up.png" Stretch="Uniform" Height="139" Width="133"></Image>
</Button>
</Grid>
</Grid>
Without App Bar Code Output:-
With App Bar Code:-
The problem is how you define your Image and its margin. I must say that I'm not quite sure why it happens, but the problem may be concerned that in xaml you define margin for the whole Page, but when you create AppBar it takes 72 pixes from bottom (that is probably the value of image's cut off part). Try this - without specyfing bottom margin:
<Button x:Name="Stay" BorderThickness="0" Width="160" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,128,0,0">
<Image Name="stayimg" Source="Resources/firstImage.png" Stretch="Uniform" Height="139" Width="133"></Image>
</Button>
I would also advise not to use Margin for 'global' positioning of your items - it will screw up in many places (different phones (resolutions) and so on). Instead use more Rows/Columns and define their height/width by percentage ("2*" for example).
1:confirm the image "appbar.add.rest.png" is exist in the path:/Assets/AppBar/
2: set the image("appbar.add.rest.png")'s build action to Content.
Steps: right click this image -> properties -> Build Action: Content.
It is because your two buttons have the bottom margin of 427. Without the application bar it is just enough. But once the application bar is added the distance between the button and the screen bottom edge is shortened.
Just remove the margins for the buttons and put them into a StackPanel like this:
<StackPanel Grid.Row="1" Margin="10,0,14,0" Orientation="Horizontal">
<Button x:Name="Stay" BorderThickness="0" Width="160" HorizontalAlignment="Left">
<Image Name="stayimg" Source="Assets/ApplicationIcon.png" Stretch="Uniform" Height="139" Width="133"></Image>
</Button>
<Button x:Name="Eat" BorderThickness="0" Width="155" HorizontalAlignment="Left">
<Image Name="Eatimg" Source="Assets/ApplicationIcon.png" Stretch="Uniform" Height="139" Width="133"></Image>
</Button>
</StackPanel>

Detect if TextBlock is visible in StackPanel

I have a StackPanel with a variable height based on available screen height/resolution, and I need to fill it up with data. The tricky part is my data is very dynamic and has headers/areas with different margins so doing a simple show x items isn't reliable.
Is there a way to detect if a TextBlock is completely visible inside a StackPanel? I'd like to not have half cut off items displayed if possible.
So this is more complicated than you are probably considering. That's because there's a lot of work to determine if there is something in front of an item. However, at its simplest, to determine if an item is visible on the screen you can use this technique.
Using this XAML:
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
<Grid x:Name="MyGrid">
<StackPanel x:Name="MyStackPanel" Orientation="Horizontal" Background="Gray">
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
<Rectangle Height="200" Width="200" Margin="50" Fill="Black" />
</StackPanel>
</Grid>
</ScrollViewer>
Use this code behind:
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
foreach (var item in MyStackPanel.Children.OfType<Windows.UI.Xaml.Shapes.Rectangle>())
{
// the box around the child
var _ItemBounds = item.TransformToVisual(null).TransformBounds(new Rect(0, 0, item.ActualWidth, item.ActualHeight));
// the box around the screen
var _Intersection = Window.Current.Bounds;
_Intersection.Intersect(_ItemBounds);
if (_Intersection.Equals(_ItemBounds))
// full
item.Fill = new SolidColorBrush(Windows.UI.Colors.Green);
else if (_Intersection.Equals(Rect.Empty))
// none
item.Fill = new SolidColorBrush(Windows.UI.Colors.Red);
else
// partial
item.Fill = new SolidColorBrush(Windows.UI.Colors.Orange);
}
}
Hope that makes sense. I always prefer examples of explanations. When you run this, visible boxes are colored green, partials are orange, and out of bounds items are painted red. Pretty simple.
related: https://stackoverflow.com/a/1517794/265706

Categories

Resources