WPF Material Design Toggle Button

Another short post today, here I modified the code for my Apple Style Toggle Button so that it more resembled the MaterialDesign toggle button. I thought of this whilst playing with the YouTube autoplay button. Here is my code:

<Style TargetType="{x:Type ToggleButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Viewbox>
                    <Border x:Name="Border" CornerRadius="10"
                            Background="#FFE2E2E2"
                            Width="40" Height="20">
                        <Border.Effect>
                            <DropShadowEffect ShadowDepth="0.5" Direction="0" Opacity="0.3" />
                        </Border.Effect>
                        <Ellipse x:Name="Ellipse" Fill="#FF909090" Stretch="Uniform"
                                 Margin="-8 -4"
                                 Stroke="Gray" StrokeThickness="0.2"
                                 HorizontalAlignment="Stretch">
                            <Ellipse.Effect>
                                <DropShadowEffect BlurRadius="10" ShadowDepth="1" 
                                                  Opacity="0.3" Direction="260" />
                            </Ellipse.Effect>
                        </Ellipse>
                    </Border>
                </Viewbox>
                <ControlTemplate.Triggers>
                    <EventTrigger RoutedEvent="Checked">
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimation Storyboard.TargetName="Ellipse"
                                                    Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
                                                    To="#FF0069F3"
                                                    Duration="0:0:0.05"
                                                    AccelerationRatio="0.7"
                                                    DecelerationRatio="0.3"/>
                                <ThicknessAnimation Storyboard.TargetName="Ellipse"
                                                    Storyboard.TargetProperty="Margin"
                                                    To="20 -4 -8 -4"
                                                    Duration="0:0:0.15" 
                                                    AccelerationRatio="0.7"
                                                    DecelerationRatio="0.3"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="Unchecked">
                        <BeginStoryboard>
                            <Storyboard>
                                <ColorAnimation Storyboard.TargetName="Ellipse"
                                                    Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
                                                    To="#FF909090"
                                                    Duration="0:0:0.05" 
                                                    AccelerationRatio="0.7"
                                                    DecelerationRatio="0.3"/>
                                <ThicknessAnimation Storyboard.TargetName="Ellipse"
                                                    Storyboard.TargetProperty="Margin"
                                                    To="-8 -4"
                                                    Duration="0:0:0.15"
                                                    AccelerationRatio="0.7"
                                                    DecelerationRatio="0.3"/>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

And finally, here is a little GIF of the toggle button:

Enjoy!

Using app.xaml and ResourceDictionaries for Cleaner WPF Customisation

When I first started making WPF forms, I was using PowerShell. This was a good starting point I think as I felt really comfortable with PowerShell which let me experiment more freely and break things in a way that I still felt comfortable.

However, this also meant putting all of my XAML into a single string. This might not sound too bad, but when you have five buttons all with slightly different templates and behaviours, the code quickly becomes messy and hard to read. Note that XAML is easy to read in the first place 😫 I was no stranger to having code that looked like this:

<Border Grid.Column="0" Grid.Row="1" Background="#FFE87E31" HorizontalAlignment="Right" Width="25" Height="25" Margin="0,0,2,0" CornerRadius="20"  BorderBrush="White" BorderThickness="1">
                <Label Name="Search_Button" Cursor="Hand" Foreground="White" Content="🔍" FontSize="12" Width="25" Height="27" Margin="-1.667,-1.667,-0.334,-0.334" />
            </Border>
<!-- OBJECT PANEL AND OBJECTS -->
            <Border HorizontalAlignment="Stretch" Grid.Column="0" Grid.Row="2" VerticalAlignment="Stretch" Background="#FF34495F" >
                <ScrollViewer VerticalScrollBarVisibility="Auto">
                    <StackPanel>
        <!-- ALL OPTION OBJECTS HERE -->
                        <Border Height="35">
                            <Border.Style>
                                <Style>
                                    <Setter Property="Border.Background" Value="#FF34495F"/>
                                    <Style.Triggers>
                                        <Trigger Property="Border.IsMouseOver" Value="True">
                                            <Setter Property="Border.Background" Value="#FF1F2A36" />
                                        </Trigger>
                                    </Style.Triggers>
                                </Style>
                            </Border.Style>
                            <Label Name="General_Information_Button" Cursor="Hand" VerticalContentAlignment="Center" Foreground="White" Content="General Information" FontFamily="Century Gothic" FontSize="14" />
                        </Border>

Horrible I know…

But when I moved to use C# with WPF, I found that I could have separate resources that could be used by multiple controls at the same time. You do this by adding a resource dictionary to the app.xaml file inside the WPF project.

Here is a quick example of what I mean. I created a Styles folder in the root of my WPF project and added a new ResourceDictionary(WPF). I called this resource dictionary “TextStyles” and it looks like this:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="FontFamily" Value="Arial"/>
        <Setter Property="FontSize" Value="28"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="Foreground" Value="White"/>
    </Style>
</ResourceDictionary>

Perfect, I then added this to my app.xaml file which now looks like this:

<Application x:Class="WPFUI.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WPFUI">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Styles/TextStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

From now on, all the text blocks in the WPF application would use the Arial font, use font size 28, be bold and also be white.

Important Notes:

  1. It’s important to add your resource dictionaries to the app.xaml file in the correct order. You want to work from top to bottom. Meaning you don’t want a resource dictionary using something from another resource dictionary below it. For example, if you are using custom colours and want your text blocks to be that colour, you would put your colour resource first and then your text block resource.
  2. If you don’t want a resource to be used everywhere in your application if you style inside the resource dictionary a name. Then you can reference the style inside your WPF XAML code.

Enjoy!

Multiple Sounds in WPF Application

So I’m making a small WPF game, which you can find here by the way 😛, and I come across a confusing and infuriating issue. WPF has two built-in audio players: SoundPlayer and MediaPlayer.

SoundPlayer: Can play audio files that are embedded resources in the application, however, this can only play one sound at once.

MediaPlayer: Cannot play audio files that are embedded resources in the application, however, this can play multiple sounds at once.

I think you can see the issue I was having. I wanted to play some background music in my game as well as some sound effects for certain actions in the game. This meant the easiest way to get this functionality was to use both of these options and save the background music to the local disk as a temporary file. Not as clean as I wanted, but it will do I guess 🤷‍♂️

First, I set up my SoundPlayer as this was the simplest one of the two. I created a new SoundPlayer object using the embedded resource:

private static readonly SoundPlayer _soundOne = new SoundPlayer(WPF.Properties.Resources.soundOne);

Then when I wanted this sound to play, I would simply use:

_soundOne.Play();

Simple enough for the SoundPlayer… Now we move onto the MediaPlayer.

First, I make sure that my audio file is set as an Embedded Resource under the Build Actions in the file’s properties in Visual Studio:

You can see from this, that I have a WAV file called “backgroundmusic.wav” which I need to save to disk, play continuously and then delete once the form is closed.

Now that we have done this, we can create the method for saving the embedded WAV file to the %temp% location on disk. This is how I did that:

public static void SaveMusicToDisk(){
    //This sets up a new temporary file in the %temp% location called "backgroundmusic.wav"
    using (FileStream fileStream = File.Create(Path.GetTempPath() + "backgroundmusic.wav")){
        
        //This them looks into the assembly and finds the embedded resource
        //inside the WPF project, under the assets folder
        //under the sounds folder called backgroundmusic.wav
        //PLEASE NOTE: this will be different to you
        Assembly.GetExecutingAssembly().GetManifestResourceStream("WPF.Assets.Sounds.backgroundmusic.wav").CopyTo(fileStream);
    }
}

Great we have now saved the embedded resource to disk, how can we play this now? 🤷‍♂️

We play this by creating a new MediaPlayer object and using the temp file location to play the audio:

//Create a new MediaPlayer object
private static readonly MediaPlayer _backgroundMusic = new MediaPlayer();

public static void StartBackgroundMusic(){
    //Open the temp WAV file saved in the temp location and called "backgroundmusic.wav"
    _backgroundMusic.Open(new Uri(Path.Combine(Path.GetTempPath(), "backgroundmusic.wav")));
    //Add an event handler for when the media has ended, this way
    //the music can be played on a loop
    _backgroundMusic.MediaEnded += new EventHandler(BackgroundMusic_Ended);
    //Start the music playing
    _backgroundMusic.Play();
}

My BackgroundMusic_Ended method looks like this and just makes sure that the music is always restarted once it has finished:

private static void BackgroundMusic_Ended(object sender, EventArgs e){
    //Set the music back to the beginning
    _backgroundMusic.Position = TimeSpan.Zro;
    //Play the music
    _backgroundMusic.Play();
}

Now that the music is playing continuously on a loop, how do we stop the music, dispose of the object and delete the temp WAV file from disk?

To stop and dispose of the MediaPlayer object is pretty easy, you can use:

public static void StopBackgroundMusic(){
    //Stops the music 
    _backgroundMusic.Stop();
    //Disposes of the MediaPlayer object
    _backgroundMusic.Close();
}

Now we go about removing the WAV file from the disk as we don’t want this to remain on the user’s computer once they have exited the application:

public static void DeleteMusicFromDisk(){
    File.Delete(Path.Combine(Path.GetTempPath(), "backgroundmusic.wav"));
}

DONE! ✔️

With all the above code and a little tinkering to fit your specific setup, you should be able to use multiple sounds at once without an issue. Enjoy!

Saving Embedded WPF Resources as Files on Disk

In this post, I am going to show you how you can save an embedded resource as a file on disk. This is useful in certain scenarios. For example, I used this to save some background music onto the computer as the native MediaPlayer couldn’t use the application paths.

First things first, you want to make sure that you have set the Build Action to Embedded Resource in the properties for each of the items:

Once you have done that, we can go about creating a method to get the resource and save it to file. For me, that is as simple as:

public static void SaveMusicToDisk(){
    //This creates a temp file in the %temp% directory called backgroundMusic.wav
    using (FileStream fileStream = File.Create(Path.GetTempPath() + "backgroundMusic.wav")){
        
        //This looks into the assembly and gets the resource by name
        //For this to work, you need to use the full application path to the resource
        //You get this by using your project name following by the folder tree to your item
        Assembly.GetExecutingAssembly().GetManifestResourceStream("WPF.Assets.Sounds.backgroundmusic.wav").CopyTo(fileStream);
    }
}

So that saves the file, what if I want to delete the file once the user wants to close the application?

For that I would use:

public static void DeleteMusicFromDisk(){
    //This looks into the %temp% folder and deletes the file called "backgroundMusic.wav"
    File.Delete(Path.Combine(Path.GetTempPath(), "backgroundMusic.wav"));
}

Peeeeerfect! 🎉 Does everything I need 😊

So, what if I wanted to save all the resources?

For that I could put all the resources into a string array and loop through them like this:

public static void SaveAllResources(){
    
    //Gets all the resources associated with the assembly and puts them into an array
    string[] resources = Assembly.GetExecutingAssembly().GetManifestResourceNames();

    foreach (string resource in resources)
    {
        //Create a new file in the %temp% for each resource
        using (FileStream fileStream = File.Create(Path.GetTempPath() + resource))
        {
            //Get the resource and save it to the current file
            Assembly.GetExecutingAssembly().GetManifestResourceStream(resource).CopyTo(fileStream);
        }
    }
}

I hope you learn something or found this helpful. Enjoy!

Caliburn.Micro Notify Change for Static Property

Normally in Caliburn.Micro and MVVM in general, you would have non-static properties that would be updated and notified like this:

private string _name;

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        NotifyOfPropertyChange(() => Name);
    }
}

However, if I had a static property, for example, if I wanted a property that could be accessed by another namespace, I would need to implement my own event handler as the default NotifyOfPropertyChange doesn’t operate on static properties.

This is the new EventHandler that I implemented:

public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
private static void NotifyStaticPropertyChanged(string propertyName)
{
    StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
}

Finally, in order to use it. I would use this instead of the first example for non-static properties:

private string _name;

public string Name
{
    get { return _name; }
    set
    {
        _name = value;
        NotifyStaticPropertyChanged(() => Name);
    }
}

I hope this helps someone. Enjoy!

Quering and Adding Info To Access Database Using C#

In this post, I will show you how I created a program to extract and add data to an Access database. Before we get started, you can see my current specifications below:

Getting values from a table:

Using System.Data.OleDB;

//Create a new list to hold all the values
List<String> values = new List<String>();

//Build the connection string and SQL string
string connectionString = @$"Provider=Microsoft.ACE.OLEDB;Data Source = C:\Path\To\Access.accdb";
string sqlString = "SELECT * FROM Table_Name";

//Create a new connection to the Access file
using (OleDbConnection connection = new OleDbConnection(connectionString)){

    //Creating a new command
    OleDbCommand command = new OleDbCommand(sqlString, connection);
    
    //Try/catch to catch errors, DON'T DO THIS IN SERIOUS PROJECTS!
    try{
        
        //Opening the connection and reading the data
        connection.Open();
        using(OleDbDataReader reader = command.ExecuteReader()){
            while(reader.Read()){
                
                //Adding the value to the values list
                values.Add(reader["Field_Name"].ToString());
            }
        }
    }catch{ }
    
    //Closing the connection
    connection.Close();
}

//Sorting the list in ascending order
values.Sort();

 

Adding a new row to the table:

Using System.Data.OleDb;

//Building the connection string and SQL string
string connectionString = @$"Provider=Microsoft.ACE.OLEDB.12.0;Data Source = C:\Path\To\Access.accdb";
string sqlString = $"INSERT INTO Table_Name(Field_Name1, Field_Name2) VALUES ('{Field_Value1}','{Field_Value2}')";

//Creating a new connection to the Access file
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
    //Build a new command
    using(OleDbCommand command = new OleDbCommand(sqlString, connection))
    {
        //Open the database connection and execute the write
        connection.Open();
        command.ExecuteReader();
    }
    //Close the database connection
    connection.Close();
}

Enjoy!

Launch Chrome and Other Applications in C#

Hi Everyone,

Short post, I just wanted to put down into writing how I open Chrome windows and other applications in C# code. This is used by one of my startup programs which allowed me to open all my most used applications with ease 🙂

First I create a Process variables using the System.Diagnostics resource:

Process process = new Process();

I then point the process variables start info filename to the location of my Chrome executable:

process.StartInfo.FileName = @"C:\Path\To\Chrome.exe";

I then add my URL to the start info arguments:

process.StartInfo.Arguments = @"https://bbc.co.uk";

Then, if I want the link to open as a new window instead of onto an existing Chrome window I use:

process.StartInfo.Arguments += " --new-windows";

Finally, I start the process:

process.Start();

Here are some different scenarios:

Opening a URL in an existing Chrome window:

Process process = new Process();
process.StartInfo.FileName = @"C:\Path\To\Chrome.exe";
process.StartInfo.Arguments = @"https://bbc.co.uk" ;
process.Start()

Opening a URL in a new Chrome window:

Process process = new Process();
process.StartInfo.FileName = @"C:\Path\To\chrome.exe";
process.StartInfo.Arguments = @"https://bbc.co.uk";
process.StartInfo.Arguments += " --new-window";
process.Start();

Opening multiple URLs in a new Chrome window:

List<String> URLs = new List<String>(){
    "https://bbc.co.uk",
    "https://mharwood.uk",
    "https://youtube.com"
}

Process process = new Process();
process.StartInfo.FileName = @"C:\Path\To\chrome.exe";
foreach (string i in URLs)
{
    process.StartInfo.Arguments += i;
}
process.StartInfo.Arguments += " --new-window";
process.Start();

Opening different programs:

List<String> Programs = new List<String>(){
    @"C:\Path\To\First\Program.exe",
    @"C:\Path\To\Second\Program.exe",
    @"C:\Path\To\Third\Program.exe"
}

foreach(string i in Programs){
    Process.Start(i);
}

I hope this is useful information for someone. Enjoy!

Performing Asynchronous Remote WMI Calls C#

This was a problem that I was stuck on for a long time. Originally, I made a program in PowerShell that myself and a couple of other people in the company used to query remote computers to retrieve certain information (SN etc). I wanted to make the move to using WPF with C# simply because of its scale, simplicity and flexibility. The things that I saw being done in WPF with C# was beyond anything I could ever dream with PowerShell.

After making the initial leap, I realised that I would how much code I would have to re-write/re-imagine into C# code. Go figure… One thing that I thought would be simple is performing asynchronous operations but this proved to be something I should use with caution. See, I could simply use Task.Run() and perform the actions, but this is like using a sledgehammer to drive in a nail. After a lot of research, I moved from using this approve to using an observer class to watch the operation and using the QueryInstancesAsync method instead of QueryInstances()

This is the code that I ended up with:

//Used to define what is returned in the async results
public static CimAsyncMultipleResults<CimInstance> GetValues(CimSession _session)
{
    return _session.QueryInstancesAsync(@"root\cimv2", "WQL", "SELECT Username FROM Win32_ComputerSystem");
}

//This watches the async progress
class CimInstanceWatcher : IObserver<CimInstance>
{
    public void OnCompleted()
    {
        Console.WriteLine("Done");
    }

    public void OnError(Exception e)
    {
        Console.WriteLine("Error: " + e.Message);
    }

    public void OnNext (CimInstance value)
    {
        Console.WriteLine("Value: " + value);
    }
}

private static void Main()
{
    //Leaving cimsession creation as sync because is happens "instantly"
    CimSession Session = CimSession.Create("PC-NAME");
    //Creating a new watcher object
    var instanceObject = new CimInstanceWatcher();
    //Subscribing the watcher object to the async call
    GetValues(Session).Subscribe(instanceObject);
    Console.ReadLine();
}

This information was provided from Microsofts forums

Enjoy!

Button Masher Game in WPF and C#

I’ve been trying to learn WPF with C# as the backend instead of PowerShell. Since there’s a lot more information on using C# over PowerShell, I decided I would take the plunge and learn as much as I could to create some apps.

This is the first app that I completed. In all honesty, it only took me around 2 hours to get the functionality completed. I did this whilst feeling ill and waiting for the wife to get back from work. I was really surprised by how easy it was for me to understand and write in C# and I was quite proud of the final outcome.

The app will probably look really different on your screen but it looks really nice on my computer. This is what the app looks like once it’s loaded:

The goal of the game is for one person to mash the A button as fast as possible and for another person to mash the B button as fast as possible. The first person to mash their respective buttons 100 times is the winner. It then displays a winning screen and allows the users to play again:

Here is a little GIF of what the game looks and feels like:

And here is the download for the game’s exe file:

ButtonMasher

Now for the nitty gritty stuff. I have included the XML and C# code used for the project below and will also include them as downloads:

XML

<Window x:Class="ButtonMasher.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:ButtonMasher"
        mc:Ignorable="d"
        Title="Button Masher" Width="450" MinHeight="145" MinWidth="300" KeyDown="WindowKeyDown" SizeToContent="Height" Icon="Icon.ico">
    <Window.Background>
        <LinearGradientBrush StartPoint="-1,-1" EndPoint="1.5,1.5" >
            <GradientStop Color="#FF018A8F" Offset="0.41" />
            <GradientStop Color="#FF00FFD6" Offset="1" />
        </LinearGradientBrush>
    </Window.Background>
    <Grid Name="Grid">
        <Grid.Background>
            <ImageBrush ImageSource="Winner_Background.jpg" Stretch="UniformToFill" Opacity="0" />
        </Grid.Background>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Label Visibility="Visible" Name="PlayerOneLabel" Content="0" FontSize="46" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontFamily="Arial"  />
        <Label Visibility="Visible" Name="PlayerTwoLabel" Content="0" FontSize="46" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1" Foreground="White" FontFamily="Arial"/>
        <ProgressBar Visibility="Visible" Name="ProgressBar1" Margin="10,5" Background="Transparent" BorderBrush="White" BorderThickness="2" Minimum="0" Maximum="100" Value="0" HorizontalAlignment="Stretch" Height="20"  Grid.Row="1" VerticalAlignment="Center" >
            <ProgressBar.Foreground>
                <LinearGradientBrush EndPoint="0,0.5" StartPoint="1,0.5">
                    <GradientStop Color="#83EAF1" Offset="0"/>
                    <GradientStop Color="#63A4FF" Offset="1"/>
                </LinearGradientBrush>
            </ProgressBar.Foreground>
        </ProgressBar>
        <ProgressBar Visibility="Visible" Name="ProgressBar2" Margin="10,5" Background="Transparent" BorderBrush="White" BorderThickness="2" Minimum="0" Maximum="100" Value="0" HorizontalAlignment="Stretch" Height="20" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5"  >
            <ProgressBar.Foreground>
                <LinearGradientBrush EndPoint="0,0.5" StartPoint="1,0.5">
                    <GradientStop Color="#83EAF1" Offset="0"/>
                    <GradientStop Color="#63A4FF" Offset="1"/>
                </LinearGradientBrush>
            </ProgressBar.Foreground>
            <ProgressBar.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform Angle="180"/>
                    <TranslateTransform/>
                </TransformGroup>
            </ProgressBar.RenderTransform>
        </ProgressBar>
        <TextBlock Name="RulesTextBlock" MouseUp="ToggleRules" Visibility="Visible" Grid.Row="2" VerticalAlignment="Bottom" HorizontalAlignment="Left" FontFamily="Arial" Foreground="White" FontSize="10" Cursor="Hand" >
            See Rules
        </TextBlock>
        <TextBlock Name="WonLabel" Text="Winner" Padding="0,40,0,0" Visibility="Collapsed" Grid.ColumnSpan="2" FontSize="46" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontWeight="Bold" TextDecorations="{x:Null}" Foreground="#FFFECE26" FontFamily="Arial">
            <TextBlock.Effect>
                <DropShadowEffect BlurRadius="1" Direction="320" ShadowDepth="2"/>
            </TextBlock.Effect>
        </TextBlock>
        <Border Name="PlayAgainBorder" Visibility="Collapsed" Grid.Row="1" Cursor="Hand" Grid.ColumnSpan="2" CornerRadius="10" Margin="0,0,0,10" HorizontalAlignment="Center" VerticalAlignment="Center" MouseUp="PlayAgain">
            <Border.Style>
                <Style>
                    <Setter Property="Border.Background" Value="#FF494949" />
                    <Setter Property="Border.BorderThickness" Value="3"/>
                    <Style.Triggers>
                        <Trigger Property="Border.IsMouseOver" Value="True" >
                            <Setter Property="Border.Background" Value="#2ecc71"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Border.Style>
            <Label Content="Play Again" VerticalAlignment="Center" Foreground="White" HorizontalAlignment="Center" VerticalContentAlignment="Center" FontSize="16" FontFamily="Arial"/>
        </Border>
        <TextBlock Name="RulesSection" Foreground="White" Grid.Row="3" Grid.ColumnSpan="2" TextWrapping="Wrap" TextAlignment="Center" Padding="20" Visibility="Collapsed" FontFamily="Arial" FontSize="14">
            The rules are simple, player one (left side) has to mash the 'A' button as fast as possible while player two (right side) has to mash the 'B' button as fast as possible. The first one to reach 100 button "mashes" wins the game!
        </TextBlock>
    </Grid>
</Window>

C#

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.Navigation;
using System.Windows.Shapes;

namespace ButtonMasher
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        //player one score
        int player1Score = 0;
        int player2Score = 0;

        //LOAD FORM
        public MainWindow()
        {
            InitializeComponent();
        }

        //UPDATE PLAYER ONE SCORE
        void UpdatePlayerOneScore()
        {
            player1Score++;
            PlayerOneLabel.Content = player1Score;
        }

        //UPDATE PLAYER TWO SCORE
        void UpdatePlayerTwoScore()
        {
            player2Score++;
            PlayerTwoLabel.Content = player2Score;
        }

        //SET WON SCREEN VISIBILITY
        void WonScreenVisibility(bool visible)
        {
            if (visible)
            {
                //show won screen
                PlayerOneLabel.Visibility = Visibility.Collapsed;
                PlayerTwoLabel.Visibility = Visibility.Collapsed;
                ProgressBar1.Visibility = Visibility.Collapsed;
                ProgressBar2.Visibility = Visibility.Collapsed;
                RulesTextBlock.Visibility = Visibility.Collapsed;
                RulesSection.Visibility = Visibility.Collapsed;
                WonLabel.Visibility = Visibility.Visible;
                PlayAgainBorder.Visibility = Visibility.Visible;
                Grid.Background.Opacity = 100;
                MinWidth = 350;
                MinHeight = 170;
            }
            else
            {
                //hide won screen
                PlayerOneLabel.Visibility = Visibility.Visible;
                PlayerTwoLabel.Visibility = Visibility.Visible;
                ProgressBar1.Visibility = Visibility.Visible;
                ProgressBar2.Visibility = Visibility.Visible;
                RulesTextBlock.Visibility = Visibility.Visible;
                RulesSection.Visibility = Visibility.Collapsed;
                WonLabel.Visibility = Visibility.Collapsed;
                PlayAgainBorder.Visibility = Visibility.Collapsed;
                Grid.Background.Opacity = 0;
                MinWidth = 300;
                MinHeight = 145;
            }
            //switch "show" or "hide" in rules textblock
            if (RulesSection.Visibility == Visibility.Visible)
            {
                RulesTextBlock.Text = "Hide Rules";
            }
            else
            {
                RulesTextBlock.Text = "Show Rules";
            }
        }

        //WON SCREEN
        void WonScreen(string player)
        {
            if(player == "1")
            {
                WonScreenVisibility(true);
                WonLabel.Text = "Player 1 won!";
            }else if(player == "2")
            {
                WonScreenVisibility(true);
                WonLabel.Text = "Player 2 won!";
            }
        }

        //RESET SCORES AND BARS
        void Reset()
        {
            player1Score = 0;
            player2Score = 0;
            PlayerOneLabel.Content = player1Score;
            PlayerTwoLabel.Content = player2Score;
            ProgressBar1.Value = player1Score;
            ProgressBar2.Value = player2Score;
        }

        //USER PRESSES BUTTON FORM
        private void WindowKeyDown(object sender, KeyEventArgs e)
        {
            //checking which key was pressed
            if (e.Key == Key.A)
            {
                UpdatePlayerOneScore(); 
            }else if(e.Key == Key.L)
            {
                UpdatePlayerTwoScore();
            }

            //calculating progress bar value
            ProgressBar1.Value = player1Score;
            ProgressBar2.Value = player2Score;

            //checking if anyone won
            if (ProgressBar1.Value > 99)
            {
                //player one has won
                WonScreen("1");

            }
            else if (ProgressBar2.Value > 99)
            {
                //player two has won
                WonScreen("2");
            }            
        }        

        //PLAY AGAIN
        private void PlayAgain(object sender, RoutedEventArgs e)
        {
            WonScreenVisibility(false);
            Reset();
        }

        //TOGGLE RULES
        void ToggleRules(object sender, RoutedEventArgs e)
        {
            if (RulesSection.Visibility == Visibility.Collapsed)
            {
                //show rules
                RulesSection.Visibility = Visibility.Visible;
                RulesTextBlock.Text = "Hide Rules";
                SizeToContent = SizeToContent.Height;
                MinHeight = 265;
            }
            else
            {
                //hide rules
                RulesSection.Visibility = Visibility.Collapsed;
                RulesTextBlock.Text = "Show Rules";
                SizeToContent = SizeToContent.Height;
                MinHeight = 145;
            }
        }
    }
}

I really hope you enjoy this little game that I created. Please feel free to use it, change it and distribute your own version at will 🙂

Enjoy!

FizzBuzz in C++

Something really out of my comfort zone here. I completed the C++ course on codecademy and did what I normally do when I’m learning a new programming language. I try to make the FizzBuzz game in as many different ways as I can to get used to the syntax and different operations.

This is was the first attempt at it and I think the easiest to do. It’s not clean but I like learning and you need to make mistakes in order to really learn something:

#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 101; i++){
        if (i % 5 == 0 & i % 3 == 0){
            std::cout << "FizzBuzz\n";
        }else if (i % 5 == 0){
            std::cout << "Fizz\n";
        }else if (i % 3 == 0){
            std::cout << "Buzz\n";
        }else{
            std::cout << i << "\n";
        }
    }
}

My second iteration was a little more sophisticated and would make any alterations to the rules of FizzBuzz easier to account for:

#include <iostream>
#include <string>
using namespace std;

int main() {
    for (int i = 0; i < 101; i++){
        string output;
        output = "";
        
        if ( i % 5 == 0 ){ output += "Fizz"; }
        if ( i % 3 == 0 ){ output += "Buzz"; }
        if ( output == "" ){ output = to_string(i); }
        cout << output << "\n";
    }
}

No doubt that I will be jumping back to create new ways when I have the time. Let me know what you come up with.

Enjoy!