C# Winform Code Snippet

As daily develop in C# .Net, I collected some of useful code snippet, including some tricky and system call. And this code snippet list will grow as long as further collecting.

1 Get the local IP and MAC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System.Net; 
using System.Net.NetworkInformation;
public string GetLocalIp()
{
string hostname = Dns.GetHostName();
IPHostEntry localhost = Dns.GetHostByName(hostname);
if (localhost.AddressList == null || localhost.AddressList.Length<=0)
{
return "";
}
IPAddress localaddr = localhost.AddressList.Where(p=>p.ToStr().StartsWith("10.")).FirstOrDefault() ;
return localaddr == null ? localhost.AddressList[0].ToStr() : localaddr.ToStr();
}
public string GetMacString()
{
string strMac = "";
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in interfaces)
{
if (ni.OperationalStatus == OperationalStatus.Up)
{
PhysicalAddress address = ni.GetPhysicalAddress();
byte[] bytes = address.GetAddressBytes();
for (int i = 0; i < bytes.Length; i++)
{
strMac = strMac + bytes[i].ToString("X2");
if (i != bytes.Length - 1)
{
strMac = strMac + "-";
}
}

break;
}
}
return strMac;
}

2 Open/Close Soft Keyboard

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System.Diagnostics;
using System.IO;
public static bool UseSoftKeyBoard = false;
public static void OpenKeyBord()
{
if (!UseSoftKeyBoard)
{
return;
}
try
{
bool findKeyBord = false;
string file = string.Empty;
string file1 = "C:\\Program Files\\Common Files\\microsoft shared\\ink\\TabTip.exe";
string file2 = "C:\\Windows\\System32\\osk.exe";

if (System.IO.File.Exists(file1))
{
findKeyBord = true;
file = file1;
}
if (!findKeyBord)
{
if (System.IO.File.Exists(file2))
{
findKeyBord = true;
file = file2;
}
}
if (!string.IsNullOrEmpty(file))
{
Process.Start(file);
}
}
catch (System.Exception ex)
{
return;
}
}
public static void CloseKeyBord()
{
if (!UseSoftKeyBoard)
{
return;
}
try
{
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
if (process.ProcessName.Equals("TabTip")
|| process.ProcessName.Equals("osk"))
{
if (!process.CloseMainWindow())
{
process.Kill();
GC.Collect();
}
}
}
}
catch (System.Exception ex)
{
return;
}
}

3 Hold and Move the Window

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System.Windows.Forms;
private static Boolean isMouseDown;
private static Point mouseStartPoint = new Point(0, 0);
private static Point formStartPosition = new Point(0, 0);
public static void MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
try
{
formStartPosition = (((Control)sender).TopLevelControl).Location;
}
catch
{
return;
}
isMouseDown = true;
mouseStartPoint.X = Control.MousePosition.X;
mouseStartPoint.Y = Control.MousePosition.Y;
}
}
public static void MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isMouseDown = false;
}
}
public static void MouseMove(object sender, MouseEventArgs e)
{
if (isMouseDown)
{
Point mouseNowPoint = Control.MousePosition;
Point formNowPosition = new Point(formStartPosition.X + mouseNowPoint.X - mouseStartPoint.X, formStartPosition.Y + mouseNowPoint.Y - mouseStartPoint.Y);
(((Control)sender).TopLevelControl).Location = formNowPosition;
}
}

//register the event on the form
public void Form_Load(object sender, EventArgs e)
{
this.MouseDown += new MouseEventHandler(SFC.Common.Common.MouseDown);
this.MouseUp += new MouseEventHandler(SFC.Common.Common.MouseUp);
this.MouseMove += new MouseEventHandler(SFC.Common.Common.MouseMove);
}

4 Read XML

1
2
3
4
5
6
7
8
9
10
11
using System.Xml

XmlDocument docxml = new XmlDocument();
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;//ignore comments
XmlReader reader = XmlReader.Create(Path, settings);
docxml.Load(reader);
reader.Close();
//XmlNode xn = docxml.GetElementsByTagName(NodeName);
XmlNodeList xnl = docxml.GetElementsByTagName(NodeName);

5 Switch Bwtween Forms

1
2
3
4
5
6
7
8
9
10
11
static class Program
{
static void Main(string[] args)
{
Form1 form1 = new Form1();
if (form1.ShowDialog() == DialogResult.OK)
{
Application.Run(new Form2());
}
}
}

6 Use TableLayoutPanel to Switch between UIs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void ShowUI(int tag)
{
for (int i = 0; i < tableLayoutPanel1.ColumnCount; i++)
{
if (i == tag)
{
tableLayoutPanel1.ColumnStyles[i].SizeType = SizeType.Percent;
tableLayoutPanel1.ColumnStyles[i].Width = 100;
}
else
{
tableLayoutPanel1.ColumnStyles[i].SizeType = SizeType.Absolute;
tableLayoutPanel1.ColumnStyles[i].Width = 0;
}
}
}

private void Form_Load(object sender, EventArgs e)
{
ShowUI(0) //show the column1 or column2 of tableLayoutPanel1
}

7 Only one running instace

1
2
3
4
5
6
7
8
9
10
11
12
using System.Diagnostics;
public void checkMultiOpen()
{
Process currentProcess = Process.GetCurrentProcess();
Process[] processesByName = Process.GetProcessesByName(currentProcess.ProcessName);
if (processesByName.Count() > 1)
{
MessageBox.Show("Only one instance is allowed.");
Application.Exit();
return;
}
}

8 Show a Clock on UI

1
2
3
4
5
6
7
8
9
10
11
12
13
public void ShowClock()
{
_clock_change = new System.Threading.Timer(_ => UIInvoke(lab_time_clock, () =>
{
lab_time_clock.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
var i_mod_value = DateTime.Now.Ticks % 1000;
if (i_mod_value == 0)
{
ClearMemory();
}
}));
_clock_change.Change(0, 1000);
}

9 Clear Memory and Interoperating with Unmanaged Code

Code that executes under the control of the runtime is called managed code. In contrast, code that runs outside the runtime is called unmanaged code. COM components, ActiveX interfaces, and Win32 API functions are all examples of unmanaged code.
Managed code is the one that is executed by the CLR of the . NET framework while unmanaged or unsafe code is executed by the operating system.
https://learn.microsoft.com/en-us/dotnet/framework/interop/
https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportattribute?view=net-8.0&redirectedfrom=MSDN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System.Runtime.InteropServices;

...

[DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);
public static void ClearMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);//the function removes as many pages as possible from the working set of the specified process.
}
}

below is a comment on the using of “SetProcessWorkingSetSize”, which demonstrates that this function is useful in two situation:

  1. An application with GUI, this function could be execute after the application initialized.
  2. You want your application to run in swap pages, and occupy less memory.

We have found out that, for a GUI application written in Delphi for Win32/Win64 or written in a similar way that uses large and heavy libraries on top of the Win32 API (GDI, etc), it is worth calling SetProcessWorkingSetSize once.

We call it with (… -1, -1) parameters, within a fraction of second after the application has fully opened and showed the main window to the user. In this case, the SetProcessWorkingSetSize(… -1, -1) releases lots of startup code that seem to not be needed any more. The memory quickly restores to about 1/3 of what it would have been without the SetProcessWorkingSetSize(… -1, -1), and does not grow more since then (unless the application allocates more memory). So we have effectively saved 2/3 of the memory of mostly startup code (loading and parsing of configuration files, initializing GUI, etc) that would not be needed to continue running the application.

If you have a GUI application, you may test on your own application the same way - just call SetProcessWorkingSetSize once and see how many memory have been released definitely.

Even for a server (service) application that don’t have GUI - I think that calling SetProcessWorkingSetSize once after the server has fully loaded and initialized might have been useful.

10 check if a character is a digit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// use system
using System;
// create class
class DigitChecker
{
static void Main()
{
// create characters
char char1 = '5';
char char2 = 'p';

// create strings
string str1 = "1234";
string str2 = "hi";

// check characters
bool a = Char.IsDigit(char1);
bool b = Char.IsDigit(char2);
bool c = Char.IsDigit(str1, 2); // position 3
bool d = Char.IsDigit(str2, 0); // position 1

// print out returned values
System.Console.WriteLine(a);
System.Console.WriteLine(b);
System.Console.WriteLine(c);
System.Console.WriteLine(d);
}
}