UWP Access MediaPlayerElement from other page - xaml

In my MainPage.xaml I have
<Grid>
<NavigationView x:Name="navView">
<NavigationView.MenuItems>
<NavigationViewItem x:Name="music" Content="My Music"/>
</NavigationView.MenuItems>
<Frame x:Name="myFrame">
<Frame.ContentTransitions>
<TransitionCollection>
<NavigationThemeTransition/>
</TransitionCollection>
</Frame.ContentTransitions>
</Frame>
</NavigationView>
<Grid Grid.Row="1">
<MediaPlayerElement x:Name="nowPlaying"
AreTransportControlsEnabled="True" x:FieldModifier="public">
<MediaPlayerElement.TransportControls>
...
</MediaPlayerElement.TransportControls>
</MediaPlayerElement>
</Grid>
</Grid>
I want to play music (pass Uri) from other Page (MyMusic) but I can't find a way to access the MediaPlayerElement. The other Page is opened in myFrame. And I want to keep the TransportControls.

You shouldn't rely on a UI element to play your media from another page. Instead, use the MediaPlayer class:
https://learn.microsoft.com/en-us/windows/uwp/audio-video-camera/play-audio-and-video-with-mediaplayer#use-mediaplayerelement-to-render-video-in-xaml
So specify your MediaPlayerElement (make sure to set AreTransportControlsEnabled value to what you need it to be):
<MediaPlayerElement x:Name="_mediaPlayerElement" AreTransportControlsEnabled="False" HorizontalAlignment="Stretch" Grid.Row="0"/>
Then you can link your element to the MediaPlayer object which you can reference in code:
_mediaPlayerElement.SetMediaPlayer(mediaPlayer);
Then play whatever you need:
_mediaPlayerElement.Source = MediaSource.CreateFromUri(new Uri("ms-appx:///Assets/example_video.mkv"));
mediaPlayer = _mediaPlayerElement.MediaPlayer;
mediaPlayer.Play();

Related

Binding current Item for Carousel of Content Views (held in Observable Collection)

I'm new to this community / Xamarin, and I've been stuck on this for a while so I need to reach out for help now.
I have a CarouselView of ContentViews and one of the view pages need to be validated so when the field is empty, I can revert back the correct carousel page using the Current Item binding BUT - although I am correctly retrieving the current item and the content view, the UI/binding isn't updating.
ContentViews is the ObservableCollection.
<Label Text="{Binding Source={x:Reference carouselView}, Path=CurrentItem,
StringFormat='Current item: {0}', FallbackValue='Current item:'}"/>
<Label Text="{Binding Source={x:Reference carouselView}, Path=Position,
StringFormat='Position: {0}'}"/>
<CarouselView
x:Name="carouselView"
IndicatorView="indicatorView"
ItemsSource="{Binding ContentViews}"
CurrentItem="{Binding CurrentItem}"
Position="{Binding Position}"
CurrentItemChanged="OnCurrentItemChanged"
PositionChanged="OnPositionChanged">
<CarouselView.ItemTemplate>
<DataTemplate>
<ContentView Content="{Binding .}" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
Do you have INotifyPropertyChanged implemented in you Binding Source?
check this , also check that the CarouselView Binding source is your desired class.

Navigate between frames using Template 10 MVVM

In a UWP app using Template 10 we have an Admin page. The Admin page has 2 pages within a frame, AdminSettings1 and AdminSettings2. We wish to navigate between AdminSettings1 and AdminSettings2 in the frame, however we find we get to the target page, but lose the containing page.
How do we navigate between pages within a frame using Template 10 MVVM without losing the containing page?
The XAML (abbreviated):
<SplitView Grid.Row="1"
x:Name="AdminSplitView"
IsPaneOpen="True"
DisplayMode="Inline">
<SplitView.Pane>
<Grid>
<ListView SelectionMode="Single"
Name="AdminListBox">
<ListViewItem Name="AdminSettings1"
IsSelected="True"
Tapped="{x:Bind AdminViewModel.GoToAdminSettings1}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Settings1"/>
</StackPanel>
</ListViewItem>
<ListViewItem Name="AdminSettings2"
Tapped="{x:Bind AdminViewModel.GoToJobformSettings2}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Settings2"/>
</StackPanel>
</ListViewItem>
</ListView>
</Grid>
</SplitView.Pane>
<SplitView.Content>
<Frame Name="AdminFrame" />
</SplitView.Content>
</SplitView>
We arrive at AdminPage like this
GoToAdmin() => NavigationService.Navigate(typeof(Views.AdminPage));
In AdminPageViewModel we navigate to AdminPage2 like this
public void GoToAdmin2() =>
NavigationService.Navigate(typeof(Views.AdminPage2));
but this loses the containing Admin page
I referred to T10 documentation for Other examples of calling Navigate. This option navigates to the page bot loses the containing page
// from inside any window
var nav = WindowWrapper.Current().NavigationServices.FirstOrDefault();
nav.Navigate(typeof(Views.AdminPage2));
I was unable test this example in the documentation as I do not understand where MyFrame comes from
// from/with a reference to a Frame
var nav = WindowWrapper.Current(MyFrame).NavigationServices.FirstOrDefault();
nav.Navigate(typeof(Views.DetailPage), this.Value);
How do we navigate between pages within a frame using Template 10 MVVM?
You can use the page cache and use this solution: https://github.com/MyToolkit/MyToolkit/wiki/Paging-Overview
from this question: WinRT/UWP Frame and Page caching: How to create new page instance on Navigate() and keep the page instance on GoBack()
this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;

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);
}

how to put images on tabs (pivots) in windows 10 app

I have read most of the Windows 10 UI design guidelines and here are some pictures of examples of a pivot navigation that is essentially a tab navigation with images: https://msdn.microsoft.com/en-us/library/windows/apps/dn997788.aspx#examples
I was unable to find out how to put images on these tabes (pivotitems).
<Pivot x:Name="mainTabs">
<PivotItem x:Name="Header1" Header="Header1" Background="{x:Null}" Foreground="{x:Null}"/>
<PivotItem x:Name="Header2" Header="Header2"></PivotItem>
<PivotItem x:Name="Header3" Header="Header3"></PivotItem>
<PivotItem x:Name="Header4" Header="Header4"></PivotItem>
<PivotItem x:Name="Header5" Header="Header5"></PivotItem>
</Pivot>
HeaderTemplate works OK for replacing text with pictures but then text is missing, and I would like to keep the text like shown in Windows 10 UI guidelines.
<Pivot x:Name="mainTabs">
<Pivot.HeaderTemplate>
<DataTemplate>
<Image Source="{Binding}"></Image>
</DataTemplate>
</Pivot.HeaderTemplate>
<PivotItem x:Name="Header1" Header="Assets/play1.png"></PivotItem>
<PivotItem x:Name="Header2" Header="Assets/play2.png"></PivotItem>
</Pivot>
Nokia Developer website had some really great article about how to make a tabbed pivot headers like official Instagram or Twitter app in Windows Phone.However , that article is not available for now because Microsoft decided to ignore all of Nokia Developer content , unfortunately.
I researched a bit and found this article instead
http://depblog.weblogs.us/2013/08/29/twitterate-your-windows-phone-app/
PivotItem headers' are being used in PivotHeaderTemplate AFAIR.Basically you can follow the article above or just change your Pivot's HeaderTemplate.
Write a converter that converts your Header property to Text and returns it.
public class ImageToTextConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var sent = value as string;
switch(sent)
{
case "Assets/play1.png":
return "Play 1 Header";
case "Assets/play2.png":
return "Play 2 Header";
default:
return string.Empty;
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Add this converter's namespace to your XAML and define it in your Resources.Then change your template as
<DataTemplate>
<StackPanel>
<Image Source="{Binding}"></Image>
<TextBlock Text="{Binding Source='',Converter={StaticResource ImageToTextConverter}}" />
</StackPanel>
</DataTemplate>
I know this post is old and no one likes to kick a dead horse, but I figured I might share my solution that doesn't rely on a value converter and allows you to simply set an image with text. Just for anyone who is looking to add images or anything to a pivot item since there does not seam to be a simple solution out there.
Add a stack panel to the pivot item header with image and text. That's it.
<Pivot x:Name="Tabs" Grid.Row="1" Grid.Column="0" >
<PivotItem>
<PivotItem.Header>
<StackPanel VerticalAlignment="Top">
<Image Width="25" Height="25" Source="../Assets/Home.png"/>
<TextBlock Text="Home Tab"/>
</StackPanel>
</PivotItem.Header>
<Grid>
<TextBlock Text="asdfasfasdfasdfasdf"/>
</Grid>
</PivotItem>
<PivotItem>
<PivotItem.Header>
<StackPanel VerticalAlignment="Top">
<Image Width="25" Height="25" Source="../Assets/Schedule.png"/>
<TextBlock Text="Home Tab"/>
</StackPanel>
</PivotItem.Header>
<Grid>
<TextBlock Text="134123475"/>
</Grid>
</PivotItem>
</Pivot>

Panorama Image Title (bind image path)

I was wondering if it's possible to bind the image path when using an Image as the Panorama Title, the reason why I need a bind for the Source is that when the user have the phone background to "white" the logo would be black, and vice versa.
This is the code I'm using:
<controls:Panorama.TitleTemplate>
<DataTemplate>
<Image Source="/PanoramaApp5;component/Images/logo.png" Margin="14,105,0,10" HorizontalAlignment="Left" Name="logo" Stretch="Fill" VerticalAlignment="Top" Width="700" Height="70"/>
<!--<TextBlock Text="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" FontSize="100" Margin="10,50,0,0" />-->
</DataTemplate>
</controls:Panorama.TitleTemplate>
If I let the default Title (which is text), it will work just fine, but I need it as an image.
Just set an empty binding for your image source, then assign it using the Title property of your panorama:
<controls:Panorama x:Name="Panorama">
<controls:Panorama.TitleTemplate>
<DataTemplate>
<Image Source="{Binding}" />
</DataTemplate>
</controls:Panorama.TitleTemplate>
</controls:Panorama>
Then from the code behind:
this.Panorama.Title = new Uri("uri of your picture");
Just to provide an example of a working version, Facebook uses this same method in the header of their Windows Phone application and instead of user binding they automatically pull photos of the user to stick together and use in the pano