I want the MediaElement called player to play mp3 after specify its source:
private void Button_Click_2(object sender, RoutedEventArgs e)
{
player.Stop();
player.Source = new Uri("ms-appx:///Assets/anata.mp3");
player.Play();
}
But it does not work, and there is no Error showed. How should I do?
Here is the original question and full code:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:cvt="using:App1"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<cvt:MusicConverter x:Key="mc"/>
</Page.Resources>
<Viewbox Visibility="Visible" Margin="20">
<Grid x:Name="root" Height="1000" Width="1800">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="0.15*"/>
<RowDefinition Height="0.15*"/>
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Grid.Column="0" Height="150" Fill="#FF4187A9" VerticalAlignment="Top"/>
<MediaElement x:Name="player" MediaFailed="player_MediaFailed" Grid.Column="1" Grid.Row="0" Margin="20" VerticalAlignment="Center" Source="Assets/bad_apple.mp4" AutoPlay="false" MediaOpened="Player_Opened" MediaEnded="Player_ended"/>
<Slider x:Name="controller" Value="{Binding ElementName=player, Path=Position, Converter={StaticResource mc}, Mode=TwoWay}" Grid.Column="1" Grid.Row="1" Height="50" Width="1000" Minimum="0" Maximum="100" VerticalAlignment="Center" />
<Button RequestedTheme="Dark" FontFamily="Segoe MDL2 Assets" Content="" Grid.Column="1" Grid.Row="2" Height="75" Width="75" Margin="449,0,0,0" Click="Button_Click_3"/>
<Button RequestedTheme="Dark" FontFamily="Segoe MDL2 Assets" Content="" Grid.Column="1" Grid.Row="2" Height="75" Width="75" Margin="750,0,0,0" Click="Button_Click_2"/>
<Button x:Name="playButton" RequestedTheme="Dark" Grid.Column="1" Grid.Row="2" Height="75" Width="75" HorizontalAlignment="Center" Click="Button_Click_1">
<SymbolIcon x:Name="ppp" Symbol="Play" />
</Button>
<Slider x:Name="vol" StepFrequency="0.05" Minimum="0.0" Maximum="1.0" SmallChange="0.05" LargeChange="0.1" Value="0.5" Grid.Column="1" Grid.Row="2" Height="30" Width="100" Margin="1019,42,167,43" ValueChanged="Slider_ValueChanged"/>
<ToggleSwitch x:Name="repeatButton" Grid.Row="2" Grid.Column="1" OnContent="repeat on" OffContent="repeat off" IsOn="False" Margin="45,0,0,0"/>
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" Text="PlayList" FontSize="72" Grid.ColumnSpan="2" Margin="140,27,1146,0"/>
<Rectangle Grid.Row="0" Grid.Column="1" Margin="20" StrokeThickness="2" Stroke="#ffffff"/>
<ListBox x:Name="lst" SelectedIndex="0" Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Margin="0,155,0,0" SelectionChanged="ListBox_SelectionChanged">
<TextBlock Text="Bad Apple" FontSize="50" />
<TextBlock Text="Anata" FontSize="50" />
<TextBlock Text="Wind" FontSize="50" />
</ListBox>
</Grid>
</Viewbox>
</Page>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace App1
{
class MusicConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return ((TimeSpan)value).TotalSeconds;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return TimeSpan.FromSeconds((double)value);
}
}
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
MediaElement mediaElement = new MediaElement();
var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
Windows.Media.SpeechSynthesis.SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("button");
mediaElement.SetSource(stream, stream.ContentType);
mediaElement.Play();
}
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int sel = lst.SelectedIndex;
string videoName;
switch (sel)
{
case 0:
videoName = "bad_apple.mp4"; break;
case 1:
videoName = "anata.mp3"; break;
case 2:
videoName = "Wind.mp3"; break;
default:
videoName = "bad_apple.mp4"; break;
}
player.Source = new Uri("ms-appx:///Assets/" + videoName);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
if (player.CurrentState.ToString()=="Paused")
{
player.Play();
ppp.Symbol = Windows.UI.Xaml.Controls.Symbol.Pause;
Debug.WriteLine(player.CurrentState.ToString());
}
else
{
player.Pause();
ppp.Symbol = Windows.UI.Xaml.Controls.Symbol.Play;
Debug.WriteLine(player.CurrentState.ToString());
}
}
private void Slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
player.Volume = (double)vol.Value;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
lst.SelectedIndex = (lst.SelectedIndex + 1) % lst.Items.Count;
Debug.WriteLine(player.CurrentState.ToString());
}
private void Button_Click_3(object sender, RoutedEventArgs e)
{
lst.SelectedIndex = (lst.SelectedIndex - 1) < 0 ? lst.Items.Count - 1 : lst.SelectedIndex - 1;
}
private void Player_Opened(object sender, RoutedEventArgs e)
{
controller.Maximum = player.NaturalDuration.TimeSpan.TotalSeconds;
}
private void Player_ended(object sender, RoutedEventArgs e)
{
if (repeatButton.IsOn)
{
player.Play();
}
else
{
lst.SelectedIndex = (lst.SelectedIndex + 1) % lst.Items.Count;
int sel = lst.SelectedIndex;
string videoName;
switch (sel)
{
case 0:
videoName = "bad_apple.mp4"; break;
case 1:
videoName = "anata.mp3"; break;
case 2:
videoName = "Wind.mp3"; break;
default:
videoName = "bad_apple.mp4"; break;
}
player.Source = new Uri("ms-appx:///Assets/" + videoName);
player.Play();
}
player.Play();
}
private void player_MediaFailed(object sender, ExceptionRoutedEventArgs e)
{
string msg = e.ErrorMessage;
Debug.WriteLine(msg);
}
}
}
The main question is Player_ended. I want this player can repeat when the repeatButton is on, and play next mp3 automatically when it is off. But it can't work. The Source is changed to new Uri successfully, but the code player.Play() seems like to be ignored. I must click playButton to play. I simplify the code and I get a new question, which is showed on the top.
Please check the following:
Check if the computer has sound turned on
Check whether the music file URL is correct (and whether the file can be played by other players)
If everything is normal, you can listen to the MediaElement.MediaFailed event. If it triggers, it indicates that the music file may be abnormal. You can get more information about the error from the event.
private void player_MediaFailed(object sender, ExceptionRoutedEventArgs e)
{
string msg = e.ErrorMessage;
Debug.WriteLine(msg);
}
By the way, in Windows 10, build 1607 and on we recommend that you use MediaPlayerElement in place of MediaElement. MediaPlayerElement has the same functionality as MediaElement, while also enabling more advanced media playback scenarios. Additionally, all future improvements in media playback will happen in MediaPlayerElement.
Update
The problem with your code is that you are calling Play() method at the wrong time.
After setting the Source for the player, the player will enter the Opening state. When you call Play() while the player is in this state, the player cannot play audio, and when the music file is loaded, it naturally enters the Pause state.
So you can delete the player.Play() method at the end of Player_ended, just set player.AutoPlay = True;
like this:
private void Player_ended(object sender, RoutedEventArgs e)
{
if (repeatButton.IsOn)
{
player.Play();
}
else
{
lst.SelectedIndex = (lst.SelectedIndex + 1) % lst.Items.Count;
player.AutoPlay = true;
}
}
By the way, When you modify lst.SelectedIndex, the ListBox_SelectionChanged event is also triggered, you do not have to call it again in Player_ended.
Best regards.
Related
i have an issue on Visual Studio(wpf) with the listbox.
If i want to insert or delete some data from the database, then they are working,but the listbox will just be refreshed if i'm clicking the menuitem for once. I think this is due to the load method, but why isn't it refreshing the data?
This is my XAML-Code:
<UserControl x:Class="WpfApplication1.AutorenBearbeiten"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="300" Loaded="UserControl_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="28*" />
<ColumnDefinition Width="36*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Medien" Grid.ColumnSpan="2"
FontSize="16" />
<ListBox x:Name="box" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=at_nachname}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel DataContext="{Binding ElementName=box,Path=SelectedItem}" Grid.Column="1" Grid.Row="1" >
<TextBlock Text="Autoren_id" />
<TextBox Text="{Binding Path=at_id}" MaxLength="5"/>
<TextBlock Text="Vorname" />
<TextBox Text="{Binding Path=at_vorname}" MaxLength="30"/>
<TextBlock Text="Nachname" />
<TextBox Text="{Binding Path=at_nachname}" MaxLength="30"/>
<TextBlock Text="Geburtsdatum" />
<TextBox MaxLength="30" Text="{Binding Path=at_gebDatum, StringFormat=dd.MM.yyyy}" />
<Button Name="speichern" Height="23" Margin="4" Click="speichern_Click">Änderungen speichern</Button>
<Button Name="loeschen" Height="23" Margin="4" Click="loeschen_Click">Löschen</Button>
<StackPanel DataContext="{Binding ElementName=box}" Grid.Column="1" Grid.Row="1" >
<TextBlock Text="Autoren_id" />
<TextBox x:Name="id" MaxLength="5"/>
<TextBlock Text="Vorname" />
<TextBox x:Name="vorname" MaxLength="30"/>
<TextBlock Text="Nachname" />
<TextBox x:Name="nachname" MaxLength="30"/>
<TextBlock Text="Geburtsdatum" />
<TextBox x:Name="datum" MaxLength="30"/>
<Button x:Name="neubutton" Height="23" Margin="4" Click="neu_Click">Neu</Button>
<TextBlock Name="submitfehler" FontWeight="Bold" Foreground="Red" />
</StackPanel>
</StackPanel>
</Grid>
</UserControl>
And this is the xaml.cs file :
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for AutorenBearbeiten.xaml
/// </summary>
public partial class AutorenBearbeiten : UserControl
{
libraryEntities6 db = new libraryEntities6();
public AutorenBearbeiten()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
var erg = db.a_autor;
erg.Load();
box.ItemsSource = erg.Local.OrderBy(m => m.at_id);
box.ItemsSource =
(from m in db.a_autor
orderby m.at_id
select m).ToList();
}
private void speichern_Click(object sender, RoutedEventArgs e)
{
try
{
db.SaveChanges();
}
catch(Exception e1)
{
submitfehler.Text = e1.Message;
}
}
private void loeschen_Click(object sender, RoutedEventArgs e)
{
a_autor am = (a_autor)box.SelectedItem;
if (am != null)
{
db.a_autor.Remove(am);
db.SaveChanges();
box.Items.Refresh();
}
}
private void neu_Click(object sender, RoutedEventArgs e)
{
a_autor autor = new a_autor();
autor.at_id = id.Text;
autor.at_vorname = vorname.Text;
autor.at_nachname = nachname.Text;
autor.at_gebDatum = Convert.ToDateTime(datum.Text);
//s1.s_k_klasse = liklassen.SelectedValue.ToString() setzt die Klasse via foreign key
//db.schuelers.AddObject(s1);
db.a_autor.Add(autor);
box.Items.Refresh();
/*
((klassen))liklassen.SelectedItem).schuelers.Add(s1); //setzt die klasse durch zuweisen zum nav.Property
lischueler.Items.Refresh(); //nötig weil das navigational seit ER 5 nicht observable ist
*/
}
}
}
A Picture from the window is below:
Window
There is no magic connection between the ListBox and the database so when you are calling the Add or Remove method of the DbContext the ListBox won't be affected.
What you should do is to set the ItemsSource property of the ListBox to an ObservableCollection<a_autor> and then call the Add/Remove method of this one besides calling the Add/Remove method of the DbContext:
System.Collections.ObjectModel.ObservableCollection<a_autor> _sourceCollection;
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
var erg = db.a_autor;
erg.Load();
_sourceCollection = new System.Collections.ObjectModel.ObservableCollection<a_autor>((from m in db.a_autor
orderby m.at_id
select m).ToList());
box.ItemsSource = _sourceCollection;
}
private void loeschen_Click(object sender, RoutedEventArgs e)
{
a_autor am = (a_autor)box.SelectedItem;
if (am != null)
{
_sourceCollection.Remove(am);
db.a_autor.Remove(am);
db.SaveChanges();
box.Items.Refresh();
}
}
private void neu_Click(object sender, RoutedEventArgs e)
{
a_autor autor = new a_autor();
autor.at_id = id.Text;
autor.at_vorname = vorname.Text;
autor.at_nachname = nachname.Text;
autor.at_gebDatum = Convert.ToDateTime(datum.Text);
_sourceCollection.Add(autor);
db.a_autor.Add(autor);
box.Items.Refresh();
}
You can create an ObservableCollection instead of binding to the List. ObservableCollection implements INotifyPropertyChanged so it can send a notification whenever something is changed in the container.
Also, I would suggest you to try
public void RefreshListBox()
{
box.ItemsSource =
(from m in db.a_autor
orderby m.at_id
select m).ToList();
}
and call this after db.SaveChanges()
You should use MVVM pattern instead of code behind and use property changes. First result in Google:
https://www.codeproject.com/Articles/819294/WPF-MVVM-step-by-step-Basics-to-Advance-Level
I hope it helps you.
Juan
What I am trying to do:
I want my program to ping a server to see if it is up.
Additionally I want to want the option to tick a checkbox for persistent pinging. That is Ping every 30 seconds (for 9999 times)
If I enter an IP address without the checkbox and press enter, it works.
If I tick the checkbox, after 30 secs, I get a successful ping (assuming the ping was successful)but it never tries a second time.
I think the problem is with the timer inside the for loop.
In easy terms I want:
-If checkbox is ticked
-then every 30 seconds for 9999 times
-run the ping method
-else run it once
I have read a lot about this but tbh, Ive reached the edge of my understanding. Any help/tips will be gratefully received!
Here is my code (the bits I think count)
using System.Net.NetworkInformation;
using System.Timers;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
namespace PingProject
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
textBoxIPaddress1.KeyDown += textBoxIPaddress1_KeyDown;
}
private void textBoxIPaddress1_KeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.IsKeyDown(Key.Enter))
{
if (every30secs1.IsChecked.Equals(true))
{
for (int pingCount = 0; pingCount < 9999; pingCount++)
{
pingAction1(this, new RoutedEventArgs());
timer = new Timer(30000);
timer.Enabled = true;
timer.Start();
timer.Elapsed += Timer_Elapsed;
}
}
else pingAction1(this, new RoutedEventArgs());
}
}
public static Timer timer;
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
timer.Dispose();
}
public void pingAction1(object sender, RoutedEventArgs e)
{
try
{
Ping Ping1 = new Ping();
PingReply pingReply1 = Ping1.Send(textBoxIPaddress1.Text, 1000);
textBoxResponseTime1.Text = (pingReply1.RoundtripTime.ToString() + "ms");
if (pingReply1.Status == IPStatus.Success)
{
successIndicatorRectangle1.Fill = new SolidColorBrush(Color.FromRgb(0, 111, 0));
textBoxError1.Text = ("Successful");
}
else
{
successIndicatorRectangle1.Fill = new SolidColorBrush(Color.FromRgb(222, 0, 0));
textBoxError1.Text = ("Not successful");
}
}
catch
{
textBoxError1.Text = ("Ping operation failed, check IP address or domain name");
successIndicatorRectangle1.Fill = new SolidColorBrush(Color.FromRgb(222, 0, 0));
}
}
private void buttonClear1_Click(object sender, RoutedEventArgs e)
{
successIndicatorRectangle1.Fill = new SolidColorBrush(Color.FromRgb(102, 102, 102));
textBoxError1.Text = (null);
textBoxIPaddress1.Text = (null);
textBoxResponseTime1.Text = (null);
}
}
}
XAML is:
<Window x:Class="PingProject.MainWindow"
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"
xmlns:local="clr-namespace:PingProject"
mc:Ignorable="d"
Title="MainWindow" Height="431" Width="753">
<Grid x:Name="um" Margin="19,35,0,10" HorizontalAlignment="Left" Width="714" RenderTransformOrigin="0.413,0.534">
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="117*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0*"/>
<ColumnDefinition Width="19*"/>
<ColumnDefinition Width="296*"/>
<ColumnDefinition Width="65*"/>
<ColumnDefinition Width="260*"/>
<ColumnDefinition Width="74*"/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="successIndicatorRectangle1" Grid.Column="2" Fill="#666666" HorizontalAlignment="Left" Height="45" Margin="0,52,0,0" Grid.Row="1" Stroke="Black" VerticalAlignment="Top" Width="611" Grid.ColumnSpan="3"/>
<Label x:Name="labelPing_Project" Content="Ping Project" HorizontalAlignment="Left" Margin="256,9,0,0" VerticalAlignment="Top" Width="95" Height="35" Grid.Column="2" FontSize="18" Grid.ColumnSpan="2" Grid.RowSpan="2"/>
<TextBox x:Name="textBoxIPaddress1" HorizontalAlignment="Left" Height="23" Margin="10,64,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="150" SelectionOpacity="0" Grid.Column="2" Grid.Row="1" ToolTip="Enter IP address" Cursor="IBeam" IsReadOnlyCaretVisible="True" ForceCursor="True"/>
<TextBox x:Name="textBoxResponseTime1" HorizontalAlignment="Left" Height="23" Margin="216,64,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="55" SelectionOpacity="0" Grid.Column="2" Grid.Row="1" ToolTip="Response Time" RenderTransformOrigin="-1.34,2.652"/>
<TextBox x:Name="textBoxError1" Grid.Column="3" Height="23" Margin="0,64,0,0" Grid.Row="1" TextWrapping="Wrap" Text="Results" VerticalAlignment="Top" Cursor="No" Grid.ColumnSpan="2" HorizontalAlignment="Left" Width="305"/>
<CheckBox x:Name="every30secs1" Content="" Grid.Column="2" HorizontalAlignment="Left" Margin="181,64,0,0" Grid.Row="1" VerticalAlignment="Top" RenderTransformOrigin="0.588,0.812" Width="20" Height="23" ToolTip="Tick this box to ping every 30 secs"/>
<Label x:Name="labelHost1" Content="Host" Grid.Column="2" HorizontalAlignment="Left" Margin="56,26,0,0" Grid.Row="1" VerticalAlignment="Top" Height="26" Width="35"/>
<Label x:Name="label1" Content="" Grid.Column="2" HorizontalAlignment="Left" Margin="150,20,0,0" Grid.Row="1" VerticalAlignment="Top" Height="26" Width="10"/>
<Label x:Name="labelResponse1" Content="Response" Grid.Column="2" HorizontalAlignment="Left" Margin="216,26,0,0" Grid.Row="1" VerticalAlignment="Top" Height="26" Width="61"/>
<Label x:Name="labelNotes1" Content="Notes" Grid.Column="4" HorizontalAlignment="Left" Margin="35,26,0,0" Grid.Row="1" VerticalAlignment="Top" Height="26" Width="41"/>
<Button x:Name="buttonClear1" Content="Clear" Grid.Column="5" HorizontalAlignment="Left" Margin="0,52,0,0" Grid.Row="1" VerticalAlignment="Top" Width="40" Height="45" IsCancel="True" Click="buttonClear1_Click"/>
</Grid>
</Window>
This is my first post here, so If I have messed it up, sorry, please be kind and guide me =0)
You have to change a bit what you are doing. IMHO the flow should be like this:
On every30secs1.CheckedChanged handler you have to check. When the checkbox is going to Checked = true, then you have to activate the timer with this code:
timer.Start();
Whenever the Checked property change to false then:
timer.Stop();
Then, on the handler of your Timer_Elapsed you have to do this:
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
timer.Stop();
for(int i = 0; i < 9999 ; i++)
{
pingAction1(this, new RoutedEventArgs());
counter ++;
Thread.Sleep(30000);
}
}
catch (Exception ex)
{
//Do something
}
finally
{
timer.Start();
}
}
I want to customize my listbox or listview to behave like the control on the following picture:
It's similar to FlipView but I've never worked with FlipView before and just saw some pictures.
I have found a good solution for me. It might helps somebody. I've changed it a little bit and It works perfectly for me.
http://www.codeproject.com/Articles/741026/WPF-FlipView
Try something like this
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<UserControl.Resources>
<DataTemplate x:Key="Test">
<Grid >
<Border Background="Red"
Loaded="RedBorder_OnLoaded" >
<!--content for this card goes here-->
<TextBlock Text="{Binding}"></TextBlock>
</Border>
<Border Background="Green"
Loaded="GreenBorder_OnLoaded"
Visibility="Collapsed" >
<!--content for this card goes here-->
<TextBlock Text="{Binding}"></TextBlock>
</Border>
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox Name="myListbox"
Margin="50"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
ItemTemplate="{StaticResource Test}" />
<StackPanel Grid.Row="1"
HorizontalAlignment="Center"
Orientation="Horizontal">
<Button Width="20"
Height="20"
Background="Black"
Click="FirstButton_OnClick" />
<Button Width="20"
Height="20"
Background="Black"
Click="SecondButton_OnClick" />
</StackPanel>
</Grid>
</UserControl>
code behind
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1
{
public partial class UserControl1 : UserControl
{
private readonly List<Border> redBorders = new List<Border>();
private readonly List<Border> greenBorders = new List<Border>();
public UserControl1()
{
InitializeComponent();
myListbox.ItemsSource = new List<string>() { "Batman", "Superman", "All others" };
}
private void RedBorder_OnLoaded(object sender, RoutedEventArgs e)
{
redBorders.Add(sender as Border);
}
private void GreenBorder_OnLoaded(object sender, RoutedEventArgs e)
{
greenBorders.Add(sender as Border);
}
private void FirstButton_OnClick(object sender, RoutedEventArgs e)
{
redBorders.ForEach(p => p.Visibility = Visibility.Visible);
greenBorders.ForEach(p => p.Visibility = Visibility.Collapsed);
}
private void SecondButton_OnClick(object sender, RoutedEventArgs e)
{
redBorders.ForEach(p => p.Visibility = Visibility.Collapsed);
greenBorders.ForEach(p => p.Visibility = Visibility.Visible);
}
}
}
usage
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1">
<wpfApplication1:UserControl1 />
it's pretty simple, but i guess you can improve it from here.
I'm trying to get my app bar to appear when I tap the 3 dots at the bottom of the screen, but when I do so it doesn't happen. Anyone know why & how this problem can be rectified?
MainPage.xaml
<Page
x:Name="pageRoot"
x:Class="HP.MainPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Exits_Expert_London_Lite.Lines_and_Stations.WC"
xmlns:common="using:Exits_Expert_London_Lite.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:q42controls="using:Q42.WinRT.Controls"
mc:Ignorable="d">
<Grid Background="Black">
<Grid.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid Name="CustomAppBarRoot" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Loaded="CustomAppBarRoot_OnLoaded"
ManipulationMode="TranslateY"
ManipulationDelta="CustomAppBarRoot_OnManipulationDelta"
ManipulationCompleted="CustomAppBarRoot_OnManipulationCompleted"
Tapped="CustomAppBarRoot_OnTapped">
<Grid.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Grid.RenderTransform>
<Grid.Background>
<SolidColorBrush Color="Black" Opacity="0.5"></SolidColorBrush>
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="DotsTextBlock" FontSize="28" Text="..." HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0 0 15 0" Tapped="DotsTextBlock_OnTapped" Width="50" Height="50" TextAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform Y="0" X="11"/>
</TextBlock.RenderTransform>
</TextBlock>
<StackPanel Name="ButtonsStackPanel" Grid.Row="1" Orientation="Horizontal">
<AppBarButton Label="tfg" Icon="Add"/>
<AppBarButton Label="tfg" Icon="Add"/>
</StackPanel>
</Grid>
<Hub>
<Hub.Header>
<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton" Margin="-1,-1,39,0" Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
Style="{StaticResource NavigationBackButtonNormalStyle}"
VerticalAlignment="Top"
AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button"/>
<TextBlock x:Name="pageTitle" Text="Page name" Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1"
IsHitTestVisible="false" TextWrapping="NoWrap" VerticalAlignment="Top"/>
</Grid>
</Hub.Header>
<HubSection Width="800" Padding="40,50,0,0">
<HubSection.Header>
<StackPanel>
<TextBlock Text="hub section 1" Style="{StaticResource HeaderTextBlockStyle}"/>
</StackPanel>
</HubSection.Header>
<DataTemplate>
<Grid>
<StackPanel>
<TextBlock Style="{StaticResource SubheaderTextBlockStyle}" Margin="0,0,0,5" TextWrapping="Wrap">
<Run Text="Hello World"/>
</TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</HubSection>
</Hub>
</Grid>
</Page>
MainPage.cs
using HP.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;
// The Hub Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=321224
namespace HP
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.Tapped += Page_OnTapped;
}
private void Page_OnTapped(object sender, TappedRoutedEventArgs tappedRoutedEventArgs)
{
if ( isAppBarShown )
HideCustomAppBar();
}
#region custom app bar
private Storyboard hideCustomAppBarStoryboard;
private Storyboard showCustomAppBarStoryboard;
private Size appBarSize;
private Size appBarButtonsSize;
private bool isAppBarShown = true;
private void CustomAppBarRoot_OnLoaded(object sender, RoutedEventArgs e)
{
appBarSize = new Size(CustomAppBarRoot.ActualWidth, CustomAppBarRoot.ActualHeight);
appBarButtonsSize = new Size(ButtonsStackPanel.ActualWidth, ButtonsStackPanel.ActualHeight);
InitializeStoryboards();
HideCustomAppBar();
}
private void ShowCustomAppBar()
{
isAppBarShown = true;
showCustomAppBarStoryboard.Begin();
}
private void HideCustomAppBar()
{
isAppBarShown = false;
hideCustomAppBarStoryboard.Begin();
}
private void DotsTextBlock_OnTapped(object sender, TappedRoutedEventArgs e)
{
if (isAppBarShown)
HideCustomAppBar();
else
ShowCustomAppBar();
}
private void InitializeStoryboards()
{
hideCustomAppBarStoryboard = new Storyboard();
showCustomAppBarStoryboard = new Storyboard();
var showDoubleAnimation = new DoubleAnimation()
{
EasingFunction = new CircleEase() {EasingMode = EasingMode.EaseInOut},
To = 0,
Duration = new Duration(TimeSpan.FromMilliseconds(200))
};
var hideDoubleAnimation = new DoubleAnimation()
{
EasingFunction = new CubicEase() {EasingMode = EasingMode.EaseInOut},
To = appBarButtonsSize.Height,
Duration = new Duration(TimeSpan.FromMilliseconds(200))
};
hideCustomAppBarStoryboard.Children.Add(hideDoubleAnimation);
showCustomAppBarStoryboard.Children.Add(showDoubleAnimation);
Storyboard.SetTarget(hideCustomAppBarStoryboard, CustomAppBarRoot);
Storyboard.SetTarget(showCustomAppBarStoryboard, CustomAppBarRoot);
Storyboard.SetTargetProperty(showCustomAppBarStoryboard, "(UIElement.RenderTransform).(TranslateTransform.Y)");
Storyboard.SetTargetProperty(hideCustomAppBarStoryboard, "(UIElement.RenderTransform).(TranslateTransform.Y)");
}
#endregion
private void CustomAppBarRoot_OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var translateTransform = (CustomAppBarRoot.RenderTransform as TranslateTransform);
double newY = e.Delta.Translation.Y + translateTransform.Y;
translateTransform.Y = Math.Max(0, Math.Min(newY, appBarButtonsSize.Height));
}
private void CustomAppBarRoot_OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
// if small appbar-position changes are made app bar should back to previous position, just like in windows phone
if (Math.Abs(e.Cumulative.Translation.Y) < 20)
isAppBarShown = !isAppBarShown;
if (!isAppBarShown)
ShowCustomAppBar();
else
HideCustomAppBar();
}
private void CustomAppBarRoot_OnTapped(object sender, TappedRoutedEventArgs e)
{
e.Handled = true; // prevents raising Page.Tapped event so appbar won't be closed on AppBar-area tap
}
}
}
Move your CustomAppBarRoot Grid after the Hub control so it renders on top. As is, the Hub control covers the CustomAppBarRoot so clicks on the ellipses go to the Hub not to the DotsTextBlock. If you give the Hub a background colour for testing this is quite obvious (leave the Background off for production):
<Hub Background="Magenta">
You could also raise the CustomAppBarRoot in the Z-order by applying the Canvas.ZIndex property; however, since your CustomAppBarRoot isn't in a Canvas this is an off-label use so I'd prefer placing the CustomAppBarRoot after the Hub in the Xaml:
<Grid Name="CustomAppBarRoot" Canvas.ZIndex="100" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Loaded="CustomAppBarRoot_OnLoaded"
There is a Segoe UI Symbol for the "More" ellipses at Unicode 0xe10c that you might use rather than using a string of periods:
<TextBlock Name="DotsTextBlock" Text="" FontSize="14" FontFamily="Segoe UI Symbol" HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0 0 15 0" Tapped="DotsTextBlock_OnTapped" Width="50" Height="50" TextAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform Y="0" X="11"/>
</TextBlock.RenderTransform>
</TextBlock>
I'm making an application in which the user inputs their desired name, which is validated before being assigned to a playerName string variable. For some reason, the input isn't being assigned to the variable, so when I run the program, a blank space shows where the name should be in blocks of text. I have no idea what's causing this. I'm using two separate windows, InputWindow and GameWindow, for the applicaton.
The XAML and codebehind for InputWindow are as follows:
<Window x:Class="COMP4_Project.InputWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="New Game" Height="120" Width="250" ResizeMode="CanMinimize">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label>Enter name:</Label>
<TextBox x:Name="textInput" Grid.Column="2" Margin="0,0,0,0" MaxLength="10"></TextBox>
<Button x:Name="Confirm" Click="Confirm_Click" Grid.Row="2" Width="80" Height="25" Content="Confirm" Margin="0,10,0,41" />
<Button x:Name="Cancel" Click="Cancel_Click" Grid.Row="2" Grid.Column="1" Width="80" Height="25" Content="Cancel" HorizontalAlignment="Right" Margin="54,10,0,41" />
</Grid>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace COMP4_Project
{
public class WorldVariables
{
public int[] worldLocale = { 0, 1, 2, 3 };
public string worldName;
public int playerScore = 0;
public string playerName;
}
/// <summary>
/// Interaction logic for InputWindow.xaml
/// </summary>
public partial class InputWindow : Window
{
private readonly WorldVariables worldVariables = new WorldVariables();
public InputWindow()
{
InitializeComponent();
}
private void Confirm_Click(object sender, RoutedEventArgs e)
{
// Text entered into the "textInput" textbox is assigned to the userInput variable
string userInput = textInput.Text;
// Validation for user input using regular expressions library
Regex r = new Regex("^[a-zA-Z]+$");
if (r.IsMatch(userInput))
{
// Assigns text held in userInput variable to playerName variable
worldVariables.playerName = userInput;
// Close input window
Close();
// Opens game window
Window win = new GameWindow();
// Sets owner of game window as the main window
win.Owner = Application.Current.MainWindow;
win.ShowDialog();
}
else
{
// Message informing user that input was invalid
MessageBox.Show("Only letters permitted; name field can't be empty. Try again!");
}
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
// Close input window
Close();
}
}
}
And this is the XAML and codebehind for GameWindow, up to the first instance where the playerName string is used in text.
<Window x:Class="COMP4_Project.GameWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Psych" Height="400" Width="500" ResizeMode="CanMinimize">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="180"/>
<ColumnDefinition Width="75" />
<ColumnDefinition Width="75" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="17" />
<RowDefinition Height="113" />
<RowDefinition Height="80" />
<RowDefinition Height="33" />
<RowDefinition Height="33"/>
<RowDefinition Height="17" />
<RowDefinition Height="17" />
<RowDefinition Height="17" />
<RowDefinition Height="66" />
</Grid.RowDefinitions>
<TextBlock x:Name="WorldName" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="3" TextWrapping="NoWrap" TextAlignment="Left" Text="World: Tunnel Entrance" />
<TextBlock x:Name="ScoreTracker" Grid.Column="5" Margin="0,0,0,0" TextWrapping="Wrap" TextAlignment="Left" Text="Score:" />
<TextBlock x:Name="ScoreCount" Grid.Column="6" Margin="0,0,0,0" TextWrapping="Wrap" TextAlignment="Left" Text="0" />
<TextBlock x:Name="Dialogue" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="6" Grid.Row="5" TextWrapping="Wrap" TextAlignment="Justify" Text="Where do you want to go? Click on the options below to change your location or click on an NPC to talk to them." />
<TextBlock x:Name="Option1" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="6" Grid.Row="6" MouseLeftButtonDown="Option1_MouseLeftButtonDown" Text=" > Go Left" />
<TextBlock x:Name="Option2" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="6" Grid.Row="7" MouseLeftButtonDown="Option2_MouseLeftButtonDown" Text=" > Go Right" />
<TextBlock x:Name="Option3" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="6" Grid.Row="8" MouseLeftButtonDown="Option3_MouseLeftButtonDown" Text=" > Enter Tunnel" />
<TextBlock x:Name="Option4" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="6" Grid.Row="6" MouseLeftButtonDown="Option4_MouseLeftButtonDown" Text=" > Go Back" Visibility="Hidden" />
<Image x:Name="Portrait" Source="C:\Psyche\Images\red1.png" Grid.Column="4" Grid.Row="1" Grid.RowSpan="4" Visibility="Hidden" />
<Image x:Name="Sprite" Source="C:\Psyche\Images\redsprite1.png" Grid.Column="2" Grid.Row="3" MouseLeftButtonDown="Sprite_MouseLeftButtonDown" />
<TextBlock x:Name="OptionBegin" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="6" Grid.Row="6" MouseLeftButtonDown="OptionBegin_MouseLeftButtonDown" Text=" > Begin Test" Visibility="Hidden" />
<TextBlock x:Name="Q1A1" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="6" Grid.Row="6" MouseLeftButtonDown="Q1A1_MouseLeftButtonDown" Text=" > Divergence from Standard Normality" Visibility="Hidden" />
<TextBlock x:Name="Q1A2" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="6" Grid.Row="7" MouseLeftButtonDown="Q1A2_MouseLeftButtonDown" Text=" > Deviation from Social Norms" Visibility="Hidden" />
<TextBlock x:Name="Q1A3" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="6" Grid.Row="8" MouseLeftButtonDown="Q1A3_MouseLeftButtonDown" Text=" > Damaging Social Negligence" Visibility="Hidden" />
<TextBlock x:Name="Q1Cont" Grid.Column="1" Margin="0,0,0,0" Grid.ColumnSpan="6" Grid.Row="6" MouseLeftButtonDown="Q1Cont_MouseLeftButtonDown" Text=" > Next question" Visibility="Hidden" />
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace COMP4_Project
{
/// <summary>
/// Interaction logic for GameWindow.xaml
/// </summary>
public partial class GameWindow : Window
{
private readonly WorldVariables worldVariables = new WorldVariables();
public GameWindow()
{
InitializeComponent();
// Set background image for window
ImageBrush myBrush = new ImageBrush();
myBrush.ImageSource =
new BitmapImage(new Uri(#"C:\Psyche\Images\background0.png", UriKind.Absolute));
this.Background = myBrush;
// Ensures non-player character sprite is visible on launching the game window
Sprite.Visibility = Visibility.Visible;
}
private void Option1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Change background image
this.Background = new ImageBrush(new BitmapImage(new Uri(#"C:\Psyche\Images\background1.png")));
// Hide character sprite
Sprite.Visibility = Visibility.Hidden;
// Hide character portrait (should not be visible regardless, this is simply a failsafe)
Portrait.Visibility = Visibility.Hidden;
// Change visible options
Option1.Visibility = Visibility.Hidden;
Option2.Visibility = Visibility.Hidden;
Option3.Visibility = Visibility.Hidden;
Option4.Visibility = Visibility.Visible;
// Alter WorldName field to match change in scene
WorldName.Text = "Location: Stream";
// Alter dialogue to match change in scene
Dialogue.Text = "There's a tree across the stream. Not much else around, though.";
}
private void Option2_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.Background = new ImageBrush(new BitmapImage(new Uri(#"C:\Psyche\Images\background2.png")));
Sprite.Visibility = Visibility.Hidden;
Portrait.Visibility = Visibility.Hidden;
Option1.Visibility = Visibility.Hidden;
Option2.Visibility = Visibility.Hidden;
Option3.Visibility = Visibility.Hidden;
Option4.Visibility = Visibility.Visible;
WorldName.Text = "Location: Forest";
Dialogue.Text = "It's pretty dark here due to the dense canopy of trees overhead. Kind of creepy when you think about it.";
}
private void Option3_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.Background = new ImageBrush(new BitmapImage(new Uri(#"C:\Psyche\Images\background3.png")));
Sprite.Visibility = Visibility.Hidden;
Portrait.Visibility = Visibility.Hidden;
Option1.Visibility = Visibility.Hidden;
Option2.Visibility = Visibility.Hidden;
Option3.Visibility = Visibility.Hidden;
Option4.Visibility = Visibility.Visible;
WorldName.Text = "Location: Tunnel";
Dialogue.Text = "There's nothing here, except a small dot of light in the distance. That might be the exit, but it's too far to check safely.";
}
private void Option4_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.Background = new ImageBrush(new BitmapImage(new Uri(#"C:\Psyche\Images\background0.png")));
Sprite.Visibility = Visibility.Visible;
Portrait.Visibility = Visibility.Hidden;
Option1.Visibility = Visibility.Visible;
Option2.Visibility = Visibility.Visible;
Option3.Visibility = Visibility.Visible;
Option4.Visibility = Visibility.Hidden;
// Revert worldname to previous text
WorldName.Text = "Location: Tunnel Entrance";
// Revert dialogue to previous text
Dialogue.Text = "Where do you want to go? Click on the options below to change your location or click on an NPC to talk to them.";
}
private void Sprite_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Hide character sprite
Sprite.Visibility = Visibility.Hidden;
// Show character portrait
Portrait.Visibility = Visibility.Visible;
// Hide all previous options to avoid overlap
Option1.Visibility = Visibility.Hidden;
Option2.Visibility = Visibility.Hidden;
Option3.Visibility = Visibility.Hidden;
Option4.Visibility = Visibility.Hidden;
// Dialogue text changes to show NPC dialogue
Dialogue.Text = "Red: Oh, hey " + worldVariables.playerName + ", you want to revise your knowledge?";
// Show option to begin test
OptionBegin.Visibility = Visibility.Visible;
}
Everything works fine aside from this bug, so any help fixing it would be appreciated.
Both of your windows are creating a new, private instance of WorldVariables:
private readonly WorldVariables worldVariables = new WorldVariables();
Setting a variable in one instance doesn't make it accessible in the other instance.
Either declare the variable as static in your WorldVariables class, so that all instances of the class are sharing a single value:
public static string playerName;
Or find a way to pass around the first instance of your WorldVariables class, so you're always referencing the instance with the player name in it.