just add some logic to hide/unhide enable/disable the oposite components. Just like this:
private void button1_Click(object sender, EventArgs e)
{
addLog("Button 1 clicked");
button1.Enabled = false;
button2.Enabled = false;
panel1.Visible = false;
panel2.Visible = true;
button2.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
addLog("Button 2 clicked");
button2.Enabled = false;
panel2.Visible = false;
panel1.Visible = true;
button1.Enabled = true;
}
works for me like a charme:

regards
Josef
EDIT:
Now, I see the problem, the mouse clicks are enqueued into windows message queue and will fire the click event on button2 although you clicked on a disabled/hidden button1.
I found the solution here: Ignoring queued mouse events
and changed the code to:
public static void ClearMouseClickQueue()
{
win32msg.NativeMessage message;
while (win32msg.PeekMessage(out message, IntPtr.Zero, (uint)win32msg.WM.WM_MOUSEFIRST, (uint)win32msg.WM.WM_MOUSELAST, 1))
{
}
}
...
private void button1_Click_1(object sender, EventArgs e)
{
addLog("Button 1 clicked");
button1.Enabled = false;
button2.Enabled = false;
panel1.Visible = false;
System.Threading.Thread.Sleep(2000);
ClearMouseClickQueue();
panel2.Visible = true;
button2.Enabled = true;
}
where PeekMessage etc is defined another class:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace PanelTest
{
public static class win32msg
{
[DllImport("coredll.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
public enum WM : uint{
/// <summary>
/// Use WM_MOUSEFIRST to specify the first mouse message. Use the PeekMessage() Function.
/// </summary>
WM_MOUSEFIRST = 0x0200,
/// <summary>
/// Use WM_MOUSELAST to specify the last mouse message. Used with PeekMessage() Function.
/// </summary>
WM_MOUSELAST = 0x020E,
}
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr handle;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
}
}
Please test.
~josef