Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions windowsforms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ If you're new to .NET Core, here are a few resources to help you understand the
| Sample Name | Description |
| ----------- | ----------- |
| [Hello World - shared source](helloworld-sharedsource) | This sample shows you how to share source between a .NET Framework WinForms application and a .NET Core WinForms application. Use this to get the full .NET Framework tooling experience while still building for .NET Core. |
| [Matching Game](matching-game) | This sample demonstrates simple event handling and timers in a .NET Core 3 WinForms application |

## Getting Started

Expand Down
321 changes: 321 additions & 0 deletions windowsforms/matching-game/MatchingGame/Form1.Designer.cs

Large diffs are not rendered by default.

177 changes: 177 additions & 0 deletions windowsforms/matching-game/MatchingGame/Form1.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace MatchingGame
{
public partial class Form1 : Form
{
// firstClicked points to the first Label control
// that the player clicks, but it will be null
// if the player hasn't clicked a label yet.
Label firstClicked = null;

// secondClicked points to the second Label control
// that the player clicks.
Label secondClicked = null;

// Use this Random object to choose random icons for the squares.
Random random = new Random();

// Each of these letters is an interesting icon
// in the Webdings font,
// and each icon appears twice in this list.
List<string> icons = new List<string>()
{
"!", "!", "N", "N", ",", ",", "k", "k",
"b", "b", "v", "v", "w", "w", "z", "z"
};

/// <summary>
/// Assign each icon from the list of icons to a random square
/// </summary>
private void AssignIconsToSquares()
{
// The TableLayoutPanel has 16 labels,
// and the icon list has 16 icons,
// so an icon is pulled at random from the list
// and added to each label.
foreach (Control control in tableLayoutPanel1.Controls)
{
Label iconLabel = control as Label;
if (iconLabel != null)
{
int randomNumber = random.Next(icons.Count);
iconLabel.Text = icons[randomNumber];
iconLabel.ForeColor = iconLabel.BackColor;
icons.RemoveAt(randomNumber);
}
}
}


public Form1()
{
InitializeComponent();
AssignIconsToSquares();
}

/// <summary>
/// Every label's Click event is handled by this event handler.
/// </summary>
/// <param name="sender">The label that was clicked.</param>
/// <param name="e"></param>
private void label_Click(object sender, EventArgs e)
{
// The timer is only on after two non-matching
// icons have been shown to the player,
// so ignore any clicks if the timer is running
if (timer1.Enabled == true)
return;

Label clickedLabel = sender as Label;

if (clickedLabel != null)
{
// If the clicked label is black, the player clicked
// an icon that's already been revealed --
// ignore the click.
if (clickedLabel.ForeColor == Color.Black)
// All done - leave the if statements.
return;

// If firstClicked is null, this is the first icon
// in the pair that the player clicked,
// so set firstClicked to the label that the player
// clicked, change its color to black, and return.
if (firstClicked == null)
{
firstClicked = clickedLabel;
firstClicked.ForeColor = Color.Black;

// All done - leave the if statements.
return;
}

// If the player gets this far, the timer isn't
// running and firstClicked isn't null,
// so this must be the second icon the player clicked
// Set its color to black.
secondClicked = clickedLabel;
secondClicked.ForeColor = Color.Black;

// Check to see if the player won.
CheckForWinner();

// If the player clicked two matching icons, keep them
// black and reset firstClicked and secondClicked
// so the player can click another icon.
if (firstClicked.Text == secondClicked.Text)
{
firstClicked = null;
secondClicked = null;
return;
}

// If the player gets this far, the player
// clicked two different icons, so start the
// timer (which will wait three quarters of
// a second, and then hide the icons).
timer1.Start();
}
}

/// <summary>
/// This timer is started when the player clicks
/// two icons that don't match,
/// so it counts three quarters of a second
/// and then turns itself off and hides both icons.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timer1_Tick(object sender, EventArgs e)
{
// Stop the timer.
timer1.Stop();

// Hide both icons.
firstClicked.ForeColor = firstClicked.BackColor;
secondClicked.ForeColor = secondClicked.BackColor;

// Reset firstClicked and secondClicked
// so the next time a label is
// clicked, the program knows it's the first click.
firstClicked = null;
secondClicked = null;
}

/// <summary>
/// Check every icon to see if it is matched, by
/// comparing its foreground color to its background color.
/// If all of the icons are matched, the player wins.
/// </summary>
private void CheckForWinner()
{
// Go through all of the labels in the TableLayoutPanel,
// checking each one to see if its icon is matched.
foreach (Control control in tableLayoutPanel1.Controls)
{
Label iconLabel = control as Label;

if (iconLabel != null)
{
if (iconLabel.ForeColor == iconLabel.BackColor)
return;
}
}

// If the loop didn’t return, it didn't find
// any unmatched icons.
// That means the user won. Show a message and close the form.
MessageBox.Show("You matched all the icons!", "Congratulations!");
Close();
}

}
}
123 changes: 123 additions & 0 deletions windowsforms/matching-game/MatchingGame/Form1.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema

Version 2.0

The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.

Example:

... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>

There are any number of "resheader" rows that contain simple
name/value pairs.

Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.

The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:

Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.

mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
34 changes: 34 additions & 0 deletions windowsforms/matching-game/MatchingGame/MatchingGameCS.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<RootNamespace>MatchingGame</RootNamespace>
<AssemblyName>MatchingGame</AssemblyName>

<!-- Don't automatically generate assembly info attributes
found in AssemblyInfo.cs. This property is useful for
applications ported from NetFx, which may have used
AssemblyInfo.cs -->
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.DesktopUI"/>
</ItemGroup>

<!-- By default, all .cs and .resx files in the current
directory or descendant directories will be included.
Optionally, they can be updated as demonstrated here
so that dependent files will appear as expected in
Visual Studio's solution explorer. -->
<ItemGroup>
<Compile Update="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<EmbeddedResource Update="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>

</Project>
19 changes: 19 additions & 0 deletions windowsforms/matching-game/MatchingGame/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Windows.Forms;

namespace MatchingGame
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Loading