Flyout won't change to dark theme? - xaml

The flyout doesn't change its theme from light to dark. I don't know why.
See my Example Code below. You can change the theme here and then the flyout remains in light theme.
MainPage.xaml
<Page>
<Page.BottomAppBar>
<CommandBar>
<AppBarButton Icon="Emoji">
<AppBarButton.Flyout>
<Flyout/>
</AppBarButton.Flyout>
</AppBarButton>
<AppBarToggleButton Checked="Checked" Unchecked="Unchecked">
<AppBarToggleButton.Icon>
<FontIcon Glyph="" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
</CommandBar>
</Page.BottomAppBar>
</Page>
MainPage.cs
public sealed partial class MainPage : Page
{
private void Checked(object sender, RoutedEventArgs e)
{
this.RequestedTheme = ElementTheme.Dark;
}
private void Unchecked(object sender, RoutedEventArgs e)
{
this.RequestedTheme = ElementTheme.Light;
}
}

If you placed content inside the flyout, you will find that they adapt to the new ElementTheme, however the flyout presenter itself won't change it's background.
The flyout presenter follows the ApplicationTheme which you can't change in code behind while the app is running, but I have two workarounds for this issue:
Specific Flyout approach, define
Define <SolidColorBrush x:Key="FlyoutBackBrush" Color="#FF2B2B2B"/> in App.Xaml resources
Define FlyoutPresenterStyle and make background uses the brush we just defined in App.Xaml
<Flyout x:Name="MyFlyout">
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="Background" Value="{StaticResource FlyoutBackBrush}"/>
</Style>
</Flyout.FlyoutPresenterStyle>
<StackPanel>
<Button Content="Button"/>
<TextBlock Text="Test"/>
</StackPanel>
</Flyout>
Change color property of the the resource FlyoutBackBrush and it will reflect in Flyout's background.
private readonly Color _darkColor = Color.FromArgb(255, 43, 43, 43);//themeresources.xaml - Default
private readonly Color _lightColor = Color.FromArgb(255, 242, 242, 242);//themeresources.xaml - Light
private void SetFlyoutBackBrush(Color color)
{
var brushKey = "FlyoutBackBrush";
if (Resources.ContainsKey(brushKey))
{
var flyoutbackBrush = Resources[brushKey] as SolidColorBrush;
if (flyoutbackBrush != null) flyoutbackBrush.Color = color;
}
}
private void Checked(object sender, RoutedEventArgs e)
{
this.RequestedTheme = ElementTheme.Dark;
SetFlyoutBackBrush(_darkColor);
}
private void Unchecked(object sender, RoutedEventArgs e)
{
this.RequestedTheme = ElementTheme.Light;
SetFlyoutBackBrush(_lightColor);
}
[Not recommended] Wide effect approach, by retrievingSystemControlBackgroundChromeMediumLowBrush's from application resources and changing it's color value [Works but read Note]
private readonly Color _darkColor = Color.FromArgb(255, 43, 43, 43);//themeresources.xaml - Default
private readonly Color _lightColor = Color.FromArgb(255, 242, 242, 242);//themeresources.xaml - Light
private void SetFlyoutBackBrush(Color color)
{
var brushKey = "SystemControlBackgroundChromeMediumLowBrush";
if (Application.Current.Resources.ContainsKey(brushKey))
{
var flyoutbackBrush = Application.Current.Resources[brushKey] as SolidColorBrush;
if (flyoutbackBrush != null) flyoutbackBrush.Color = color;
}
}
private void Checked(object sender, RoutedEventArgs e)
{
this.RequestedTheme = ElementTheme.Dark;
SetFlyoutBackBrush(_darkColor);
}
private void Unchecked(object sender, RoutedEventArgs e)
{
this.RequestedTheme = ElementTheme.Light;
SetFlyoutBackBrush(_lightColor);
}
Note This will affect all Flyouts and Pickers across application as they all use SystemControlBackgroundChromeMediumLowBrush.

I found no so nice solution for this problem, but it is easy and works :)
http://blog.kurpio.com/2016/04/19/perelki-uwp-2-flyout-w-commandbar-obejscie-buga/
You can set SystemControlBackgroundChromeMediumBrush as a brush of Grid in Flyout Content.
<AppBarButton Label="Szukaj"
Icon="Find">
<AppBarButton.Flyout>
<Flyout Placement="Bottom">
<Flyout.Content>
<Grid Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}"
Margin="-15"
Padding="15"
Width="285">
<TextBox Header="Szukaj:"
Width="175"
HorizontalAlignment="Left" />
<AppBarButton Label="Szukaj"
Icon="Find"
HorizontalAlignment="Right" />
</Grid>
</Flyout.Content>
</Flyout>
</AppBarButton.Flyout>
</AppBarButton>
...notice to set Margin and Padding of Grid to fill the Flyout.

Related

How to drag around a TeachingTip?

TeachingTip does not seem Pointer* events have implemented, therefore I had to add a Grid to hero content to get those events fired :
<TeachingTip IsOpen="True" Title="City Village" Subtitle="Legend highlighted in HeroContent">
<TeachingTip.HeroContent>
<Grid PointerMoved="OnPointerMoved" PointerPressed="OnPointerPressed" PointerReleased="OnPointerReleased" PointerCanceled="OnPointerReleased">
<Image Source="ms-appx:///Assets/Qantas.svg" Margin="5"/>
</Grid>
</TeachingTip.HeroContent>
<TeachingTip.Content>
<GridView ItemsSource="{x:Bind ViewModel.Items}" Margin="5">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate x:DataType="model:ChartLegendItem">
<StackPanel>
<Line Stroke="{x:Bind Color, Converter={StaticResource HexBrushConverter}}" X1="0" Y1="0" X2="10" Y2="0" StrokeThickness="5"/>
<TextBlock Text="{x:Bind Caption}"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</TeachingTip.Content>
</TeachingTip>
Also added the handlers but this is not moving the control :
private void OnPointerPressed(object sender, PointerRoutedEventArgs args)
{
var point = args.GetCurrentPoint(this);
if (point.Properties.IsLeftButtonPressed)
{
_isDragging = true;
_clickPosition = point;
CapturePointer(args.Pointer);
args.Handled = true;
}
}
private void OnPointerReleased(object sender, PointerRoutedEventArgs args)
{
_isDragging = false;
ReleasePointerCapture(args.Pointer);
args.Handled = true;
}
private void OnPointerMoved(object sender, PointerRoutedEventArgs args)
{
if (_isDragging)
{
var currentPosition = args.GetCurrentPoint(this);
if (RenderTransform is not TranslateTransform)
{
RenderTransform = new TranslateTransform();
}
var p = new Point(currentPosition.Position.X, currentPosition.Position.Y);
var p1 = RenderTransform.TransformPoint(p);
args.Handled = true;
}
}
Is it needed to be on a Canvas or the transformation itself is inappropriate ?

How to create an identical button to the one in 'Settings' page?

I want to create buttons on my UWP/XAML app similar to the buttons on the Windows 'Settings' page using the WinUI 3 library. The gallery didn't show this kind of button with an icon and a title/description. I'm wondering how it can be accomplished since I am developing an app that mostly serves as a portal to go to websites and navigate easily through web/PC apps. Any help would be appreciated.
I want the buttons to simply redirect the user to a NavigationView page (Page5.xaml)
I have a NavigationView on MainPage.xaml and these buttons are going on Page4, so I'm not sure how I can program the buttons to go to Page5.xaml
https://i.stack.imgur.com/7Uff8.png
You can create a usercontrol and use some of my code:
MyUserControl.xaml:
<Grid x:Name="MainGrid" PointerEntered="Grid_PointerEntered" PointerExited="Grid_PointerExited" PointerPressed="FontIcon_PointerPressed" Margin="20,5,20,5" Height="70" CornerRadius="5" Padding="{StaticResource ExpanderHeaderPadding}" HorizontalAlignment="Stretch" Background="{ThemeResource ExpanderHeaderBackground}" BorderThickness="{ThemeResource ExpanderHeaderBorderThickness}" BorderBrush="{ThemeResource ExpanderHeaderBorderBrush}">
<StackPanel Orientation="Horizontal" Margin="0,20,0,20">
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" Margin="0,0,20,0"/>
<TextBlock FontSize="24" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Font"/>
</StackPanel>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" HorizontalAlignment="Right" Margin="0,0,20,0"/>
</Grid>
MyUserControl1.xaml.cs:
public MyUserControl1()
{
this.InitializeComponent();
var color = (MainGrid.Background as SolidColorBrush).Color;
color.A = 20;
MainGrid.Background = new SolidColorBrush(color);
}
private void FontIcon_PointerPressed(object sender, PointerRoutedEventArgs e)
{
if (e.GetCurrentPoint(sender as UIElement).Properties.IsLeftButtonPressed)
{
//Do whatever you want
Debug.WriteLine("Pressed");
}
}
//Change the color on hover:
private void Grid_PointerEntered(object sender, PointerRoutedEventArgs e)
{
var color = (MainGrid.Background as SolidColorBrush).Color;
color.A = 50;
MainGrid.Background = new SolidColorBrush(color);
}
private void Grid_PointerExited(object sender, PointerRoutedEventArgs e)
{
var color = (MainGrid.Background as SolidColorBrush).Color;
color.A = 20;
MainGrid.Background = new SolidColorBrush(color);
}

Disable ScrollView in Xamarin Forms without disabling buttons

I have the following XAML. I want to target phones with a scrollview, and want scrolling disabled on a tablet.
<ScrollView InputTransparent="False" Orientation="Both" >
<ScrollView.IsEnabled>
<OnIdiom x:TypeArguments="x:Boolean">
<OnIdiom.Phone>True</OnIdiom.Phone>
<OnIdiom.Tablet>True</OnIdiom.Tablet>
</OnIdiom>
</ScrollView.IsEnabled>
<StackLayout VerticalOptions="FillAndExpand" BackgroundColor="White" >
<StackLayout.HorizontalOptions>
<OnIdiom x:TypeArguments="LayoutOptions">
<OnIdiom.Tablet>FillAndExpand</OnIdiom.Tablet>
<OnIdiom.Phone>Start</OnIdiom.Phone>
</OnIdiom>
</StackLayout.HorizontalOptions>
<Grid BackgroundColor="White" HeightRequest="65" MinimumHeightRequest="65">
<Grid.HorizontalOptions>
<OnIdiom x:TypeArguments="LayoutOptions">
<OnIdiom.Tablet>CenterAndExpand</OnIdiom.Tablet>
<OnIdiom.Phone>Start</OnIdiom.Phone>
</OnIdiom>
</Grid.HorizontalOptions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<WebView x:Name="webViewBtn1" HeightRequest="65" Grid.Column="0" Grid.ColumnSpan="1" VerticalOptions="FillAndExpand" BackgroundColor="White">
<WebView.HorizontalOptions>
<OnIdiom x:TypeArguments="LayoutOptions">
<OnIdiom.Tablet>CenterAndExpand</OnIdiom.Tablet>
<OnIdiom.Phone>Start</OnIdiom.Phone>
</OnIdiom>
</WebView.HorizontalOptions>
<WebView.WidthRequest>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Tablet>770</OnIdiom.Tablet>
<OnIdiom.Phone>300</OnIdiom.Phone>
</OnIdiom>
</WebView.WidthRequest>
</WebView>
<Button Grid.Column="0" Grid.ColumnSpan="1" x:Name="btn1" Clicked="btn1_Clicked" BackgroundColor="Transparent" TextColor="Transparent" BorderColor="White" />
</Grid>
</StackLayout>
</ScrollView>
the buttons no longer allow the user to click on them if I set ScrollView.IsEnabled the following way:
<OnIdiom.Tablet>False</OnIdiom.Tablet>
My assumption that using InputTransparent was not correct. Is there a way to make the buttons clickable inside a scroll view that has scrolling disabled?
I essentially am looking for something like Orientation=None, but that is not an option.
You need to write a CustomRenderer for disabling the scroll.
On iOS UIScrollView has a ScrollEnabled property
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
// IsScrollEnabled just a custom property
// handled it in OnPropertyChanged too
ScrollEnabled = Element.IsScrollEnabled;
}
Android it is a bit tricky, there is not direct property. We intercept the touch event and return without handling it.
public override bool OnInterceptTouchEvent(MotionEvent ev)
{
if (Element.IsScrollEnabled)
{
return base.OnInterceptTouchEvent(ev);
}
else
{
return false;
}
}
public override bool OnTouchEvent(MotionEvent ev)
{
if (Element.IsScrollEnabled)
{
return base.OnTouchEvent(ev);
}
else
{
return false;
}
}
I ended up using this approach to disable vertical scrolling on an iPad, which is my target device. Not perfect for android 7 inch tablets, but oh well:
<ScrollView.Orientation>
<OnPlatform x:TypeArguments="ScrollOrientation">
<On Platform="iOS">
<OnIdiom x:TypeArguments="ScrollOrientation">
<OnIdiom.Phone>Both</OnIdiom.Phone>
<OnIdiom.Tablet>Horizontal</OnIdiom.Tablet>
</OnIdiom>
</On>
<On Platform="Android">
<OnIdiom x:TypeArguments="ScrollOrientation">
<OnIdiom.Phone>Both</OnIdiom.Phone>
<OnIdiom.Tablet>Both</OnIdiom.Tablet>
</OnIdiom>
</On>
<On Platform="UWP">Both</On>
</OnPlatform>
</ScrollView.Orientation>
In the latest version of Xamarin Forms, you can set the Orientation to Neither.
scrollV.Orientation = ScrollOrientation.Neither;
Cool and compact way to disable scrolling in Xamarin Forms without affecting it's children through ScrollEnabled extension method:
public static class ScrollViewEx
{
/// <summary>
/// Disables scrollview by modifying Scrolled Event and attaching itself to ScrollView's binding context
/// Scrolled event sends it back to the original x,y
/// </summary>
public class DisabledScrollClass : IDisposable
{
private double ScrollX;
private double ScrollY;
private object OldContext;
private ScrollView Parent;
public DisabledScrollClass(ScrollView parent)
{
Parent = parent;
ScrollX = parent.ScrollX;
ScrollY = parent.ScrollY;
OldContext = parent.BindingContext;
parent.Scrolled += Scrolled;
parent.BindingContext = this;
}
private void Scrolled(object sender, ScrolledEventArgs e)
{
(sender as ScrollView)?.ScrollToAsync(ScrollX, ScrollY, false);
}
public void Dispose()
{
Parent.Scrolled -= Scrolled;
Parent.BindingContext = OldContext;
}
}
public static ScrollView ScrollEnabled(this ScrollView scroll, bool isEnabled)
{
DisabledScrollClass binding = scroll.BindingContext as DisabledScrollClass;
if (isEnabled && binding != null)
binding.Dispose();
if (!isEnabled && binding == null)
_ = new DisabledScrollClass(scroll);
return scroll;
}
}

UWP ListView Item context menu

I'm searching internet for how to add context menu for ListView. So far I've found one that actually displays context
<ListView>
...
RightTapped="ContactsListView_RightTapped" >
...
<ListView.Resources>
<MenuFlyout x:Name="allContactsMenuFlyout">
<MenuFlyout.Items>
<MenuFlyoutItem x:Name="Edit" Text="Edit"/>
<MenuFlyoutItem x:Name="Remove" Text="Remove" Click="Remove_Click"/>
</MenuFlyout.Items>
</MenuFlyout>
</ListView.Resources>
...
</ListView>
private void ContactsListView_RightTapped(object sender, RightTappedRoutedEventArgs e) {
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
}
private void Remove_Click(object sender, RoutedEventArgs e) {
}
The problem is I'm not able to get item on which the context menu was displayed. Another issue is that the context menu is displayed also outside of list view item (e.g. on borders). And since the event that is triggered is RightTapped, I'm not sure if the context menu would be displayed on long click on mobile devices. I cannot test it because my emulators are not currently working. Since it should be universal windows app I was expecting some really easy and efficient way of creating context menus for ListView items.
The problem is I'm not able to get item on which the context menu was displayed.
For this problem, if you add data to the ListView like this:
<ListView RightTapped="ListView_RightTapped">
<x:String>First Item</x:String>
<x:String>Second Item</x:String>
<x:String>Third Item</x:String>
<x:String>Fourth Item</x:String>
<ListView.Resources>
<MenuFlyout x:Name="allContactsMenuFlyout">
<MenuFlyout.Items>
<MenuFlyoutItem x:Name="Edit" Text="Edit" />
<MenuFlyoutItem x:Name="Remove" Text="Remove" Click="Remove_Click" />
</MenuFlyout.Items>
</MenuFlyout>
</ListView.Resources>
</ListView>
You can get the item's context in the RightTapped event like this:
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext;
}
In this scenario, "a" will directly get the string format content of clicked item.
If you add your data to ListView using DataTemplate like this:
<ListView RightTapped="ListView_RightTapped" ItemsSource="{x:Bind list}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding text}" />
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Resources>
<MenuFlyout x:Name="allContactsMenuFlyout">
<MenuFlyout.Items>
<MenuFlyoutItem x:Name="Edit" Text="Edit" />
<MenuFlyoutItem x:Name="Remove" Text="Remove" Click="Remove_Click" />
</MenuFlyout.Items>
</MenuFlyout>
</ListView.Resources>
</ListView>
and usually when using DataTemplate, we add data by ObservableCollection like this:
private ObservableCollection<List> list = new ObservableCollection<List>();
public MainPage()
{
this.InitializeComponent();
list.Clear();
list.Add(new List { text = "Item 1" });
list.Add(new List { text = "Item 2" });
list.Add(new List { text = "Item 3" });
list.Add(new List { text = "Item 4" });
list.Add(new List { text = "Item 5" });
}
"List" class is quite simple here for test:
public class List
{
public string text { get; set; }
}
Then also we can get the DataContext in the RightTapped event:
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext;
}
But this time, "a" is actually the 'List' object (please refer to the "List" class) inside the item, because the content of the item is now a 'List' object, not a string any more. So we can get the text property of this object like this:
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext as List;
var content = a.text;
}
I think eventually you want to edit the content in the Button click event of the Flyout, you can do it for example like this:
private string content;
private void ListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext as List;
content = a.text;
}
private void Remove_Click(object sender, RoutedEventArgs e)
{
foreach (var item in list.ToList())
{
if (item.text == content)
{
list.Remove(item);
}
}
content = "";
}
Another issue is that the context menu is displayed also outside of list view item (e.g. on borders).
Can you explain this? I can't quite understand it. You mean displaying the content for example in the Flyout? If so, I think the method above can solve this problem. If not, you can leave a comment, and I will see if this problem can be resolved.
And since the event that is triggered is RightTapped, I'm not sure if the context menu would be displayed on long click on mobile devices.
I think that "long click" event here indicates the Holding event like this?
private void ListView_Holding(object sender, HoldingRoutedEventArgs e)
{
ListView listView = (ListView)sender;
allContactsMenuFlyout.ShowAt(listView, e.GetPosition(listView));
var a = ((FrameworkElement)e.OriginalSource).DataContext as List;
content = a.text;
}
I just test it on the Mobile Emulator, it works fine. Although I wrote a quite long answer here, but the key point is quite simple, you can just use ((FrameworkElement)e.OriginalSource).DataContext to get the Context of the item.
Use Command instead of Click event. You can pass the clicked item in CommandParameter
<MenuFlyout x:Name="allContactsMenuFlyout">
<MenuFlyout.Items>
<MenuFlyoutItem x:Name="Edit" Text="Edit"/>
<MenuFlyoutItem x:Name="Remove" Text="Remove" Command="{Binding Path=DeleteItemTappedCommand}" CommandParameter="{Binding ElementName=ArchivedMessages_ListView, Path=SelectedItem}"/>
</MenuFlyout.Items>
</MenuFlyout>
Inside your ViewModel
public DelegateCommand<object> DeleteItemTappedCommand { get; set; }
public YourViewModel()
{
DeleteItemTappedCommand = new DelegateCommand<object>(DeleteItemClicked);
}
private void DeleteItemClicked(object obj)
{
// adjust object type to your templated source type
}
or for the CommunityToolkit.MVVM users:
[ICommand]
private void DeleteItemClicked(object obj)
{
// adjust object type to your templated source type
}
Add flyout in the datatemplate. Use command to deal with the events.
See sample code here:
<DataTemplate x:Name="ListItemTemplate" >
<Grid x:Name="gridItem" RightTapped="gridItem_RightTapped">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Name="imgProduct" Width="50" Height="50" Grid.Column="0" Source="{Binding ProductUrl}" Margin="0,5,10,5" VerticalAlignment="Center" ></Image>
<TextBlock Name="tbName" Text="{Binding Name}" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" ></TextBlock>
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Delete" Command="{Binding DataContext.DeleteCommand, ElementName=contentGrid}" CommandParameter="{Binding}" />
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
</Grid>
</DataTemplate>
Code behind:
private void gridItem_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
FlyoutBase.ShowAttachedFlyout(sender as FrameworkElement);
}
You can get the full solution here: https://code.msdn.microsoft.com/How-to-implement-flyout-ef52517f

Play audio file in the background in Windows8 app?

I am developing an app that displays information while at the same time plays audio file in the background. This is a Windows 8 tablet app. Any help or suggestion is helpful.
Thanks
In the XAML, you will have a MediaElement with the following attributes
<ContentControl x:Name="Host">
<MediaElement Source="Assets/myMusic.mp3" IsLooping="True" AutoPlay="True" AudioCategory="BackgroundCapableMedia" PosterSource="/Images/placeholder-sdk.png" VerticalAlignment="Center" HorizontalAlignment="Center" Name="myMediaElement" Height="350" Width="640" />
</ContentControl>
In the App bar, you can have some buttons for media control like
<Page.BottomAppBar>
<AppBar Opened="BottomAppBar_Opened" Background="#FF3C3838" x:Name="BottomAppBarColors" Padding="10,0,10,0" AutomationProperties.Name="Bottom App Bar Colors">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="50*"/>
</Grid.ColumnDefinitions>
<StackPanel x:Name="LFullScreenLandscapeViewGrid" Orientation="Horizontal" Grid.Column="0" HorizontalAlignment="Left">
<Button x:Name="Play" Click="PlayButton_Click" Style="{StaticResource PlayAppBarButtonStyle}" Tag="Play"/>
<Button x:Name="Stop" Click="StopButton_Click" Style="{StaticResource StopAppBarButtonStyle}" Tag="Stop"/>
</StackPanel>
<StackPanel Visibility="Collapsed" x:Name="PortraitViewGrid" Orientation="Horizontal" Grid.ColumnSpan="2" HorizontalAlignment="Right">
<Button x:Name="PauseCollapsed" Click="PauseButton_Click" Style="{StaticResource PauseAppBarButtonStyle}" Tag="Pause"/>
<Button x:Name="PlayCollapsed" Click="PlayButton_Click" Style="{StaticResource PlayAppBarButtonStyle}" Tag="Play"/>
<Button x:Name="StopCollapsed" Click="StopButton_Click" Style="{StaticResource StopAppBarButtonStyle}" Tag="Stop"/>
</StackPanel>
</Grid>
</AppBar>
</Page.BottomAppBar>
In the .CS code file, you can control the mediaelement object.
private void PauseButton_Click(object sender, RoutedEventArgs e)
{
myMediaElement.Pause();
}
private void StopButton_Click(object sender, RoutedEventArgs e)
{
myMediaElement.Stop();
}
private void ForwardButton_Click(object sender, RoutedEventArgs e)
{
myMediaElement.DefaultPlaybackRate = 0.0;
myMediaElement.PlaybackRate = 2.0;
}
private void RewindButton_Click(object sender, RoutedEventArgs e)
{
myMediaElement.DefaultPlaybackRate = 0.0;
myMediaElement.PlaybackRate = -1.0;
}
If you have multiple screens that use the media and controls to play, pause and stop the media file, then it's better to write code for these events once and then use it from different screens. I have seen people writing the following code in every screen they use the media.
private void PauseButton_Click(object sender, RoutedEventArgs e)
{
myMediaElement.Pause();
}
private void StopButton_Click(object sender, RoutedEventArgs e)
{
myMediaElement.Stop();
}
private void ForwardButton_Click(object sender, RoutedEventArgs e)
{
myMediaElement.DefaultPlaybackRate = 0.0;
myMediaElement.PlaybackRate = 2.0;
}
private void RewindButton_Click(object sender, RoutedEventArgs e)
{
myMediaElement.DefaultPlaybackRate = 0.0;
myMediaElement.PlaybackRate = -1.0;
}
So instead of repeating the code in every screen, follow a good event pattern to reduce duplicate code
The best thing is to use MVVM pattern and you can find a sample at http://code.msdn.microsoft.com/windowsapps/Background-Audio-c-Metro-d2fc7719/view/SourceCode
So the design is to write up the code in one common place and fire them from the front end UI.
You need to use a MediaElement.