473,395 Members | 1,530 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Forms.Panel and the KeyUp event (message)

I know that Panel (and most of it's derivitives) don't raise keyboard
events. I *really* need to catch keyboard events though so I've been
googling the topic and have found quite a few suggestions. The one
suggestion I've found that makes the most sense isn't working for me and
after this most recent failure I'm really at a loss! ;0)

I'm overriding WndProc and checking the Message.Msg property for the
WM_KEYUP message.

If anyone has any ideas for me I would really appreciate it!
Here is a complete application that shows the failure.

<code>
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace PanelKeyEventExample
{
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private MyPanel panel1;

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new MyPanel();
this.SuspendLayout();
//
// panel1
//
this.panel1.Location = new System.Drawing.Point(46, 49);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(200, 100);
this.panel1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.panel1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}

#endregion
}

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

public class MyPanel : Panel
{
const int WM_KEYUP = 0x0101;

protected override void WndProc(ref Message m)
{
if (m.Msg == WM_KEYUP)
{
Console.WriteLine("KeyUp message caught");
}

base.WndProc(ref m);
}
}
}
</code>
Jun 27 '08 #1
5 6061
Hi,

Actually, you can trap key events in a panel just fine, but the problem is
the panel doesn't focus easily. One way to focus on a panel is to handle the
MouseDown event and set focus there.

Try this

public class MyPanel : Panel
{
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
}

protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);

Focus();
}
}
--
Happy Coding!
Morten Wennevik [C# MVP]
"sklett" wrote:
I know that Panel (and most of it's derivitives) don't raise keyboard
events. I *really* need to catch keyboard events though so I've been
googling the topic and have found quite a few suggestions. The one
suggestion I've found that makes the most sense isn't working for me and
after this most recent failure I'm really at a loss! ;0)

I'm overriding WndProc and checking the Message.Msg property for the
WM_KEYUP message.

If anyone has any ideas for me I would really appreciate it!
Here is a complete application that shows the failure.

<code>
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace PanelKeyEventExample
{
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private MyPanel panel1;

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new MyPanel();
this.SuspendLayout();
//
// panel1
//
this.panel1.Location = new System.Drawing.Point(46, 49);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(200, 100);
this.panel1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.panel1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}

#endregion
}

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

public class MyPanel : Panel
{
const int WM_KEYUP = 0x0101;

protected override void WndProc(ref Message m)
{
if (m.Msg == WM_KEYUP)
{
Console.WriteLine("KeyUp message caught");
}

base.WndProc(ref m);
}
}
}
</code>
Jun 27 '08 #2
Hi Morten,

Thank you for the reply! I hadn't thought about the focus issue, I thought
that all messages would run the WndProc regardless of focus state. I will
give your suggestion a try. I'm not sure what effect it will have on the
operation of my control.

You seem to really know your WinForm and Control stuff from posts I've read
by you. If you don't mind I'd like to describe the control I have and the
issue I'm trying to solve.

The purpose of the control is to allow my user's to select pages from a
document, it's similar in function to the "thumbnails" in acrobat reader.

I have implemented the control as a derived FlowLayoutPanel that I populate
with CheckBox controls. Each checkbox control has it's Image property set
to one of the pages in my source image[].

It works great, fulfills the use case, quick, etc, etc.

I'm always trying to tweak my user interfaces, especially data entry
applications, so the user doesn't feel the urge to grab the mouse and click.
With my page selection control they tend to use the mouse to click on the
thumbnails. *I* know it's possible to tab and spacebar to select the
checkboxes, etc, etc but for my users that is a bit too awkward.

My plan was to handle the numeric key presses (1-9) to select the
corresponding pages. This is limited in that it will only support 9 pages,
but for 99% of the time this will be fine.

As my control is essentially a FlowLayoutpanel with child controls it seems
I need to handle the key presses on the FlowLayoutPanel.

In your opinion, am I on the right track?

I'm concerned that if I set focus to the *Panel programmatically (per your
suggestion) then if a user clicks on a checkbox control with the mouse the
focus will be removed from the FlowLayoutPanel. Then subsequent 1-9 presses
won't be caught by the Panel.

I will try it and see what happens, I just wanted to run the design my you
for any thoughts you might have or suggestions.

Thanks again,
Steve
"Morten Wennevik [C# MVP]" <Mo************@hotmail.comwrote in message
news:61**********************************@microsof t.com...
Hi,

Actually, you can trap key events in a panel just fine, but the problem is
the panel doesn't focus easily. One way to focus on a panel is to handle
the
MouseDown event and set focus there.

Try this

public class MyPanel : Panel
{
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
}

protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);

Focus();
}
}
--
Happy Coding!
Morten Wennevik [C# MVP]
"sklett" wrote:
>I know that Panel (and most of it's derivitives) don't raise keyboard
events. I *really* need to catch keyboard events though so I've been
googling the topic and have found quite a few suggestions. The one
suggestion I've found that makes the most sense isn't working for me and
after this most recent failure I'm really at a loss! ;0)

I'm overriding WndProc and checking the Message.Msg property for the
WM_KEYUP message.

If anyone has any ideas for me I would really appreciate it!
Here is a complete application that shows the failure.

<code>
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace PanelKeyEventExample
{
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private MyPanel panel1;

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new MyPanel();
this.SuspendLayout();
//
// panel1
//
this.panel1.Location = new System.Drawing.Point(46, 49);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(200, 100);
this.panel1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.panel1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}

#endregion
}

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

public class MyPanel : Panel
{
const int WM_KEYUP = 0x0101;

protected override void WndProc(ref Message m)
{
if (m.Msg == WM_KEYUP)
{
Console.WriteLine("KeyUp message caught");
}

base.WndProc(ref m);
}
}
}
</code>

Jun 27 '08 #3
I'm concerned that if I set focus to the *Panel programmatically (per your
suggestion) then if a user clicks on a checkbox control with the mouse the
focus will be removed from the FlowLayoutPanel. Then subsequent 1-9
presses won't be caught by the Panel.
Turns out this is indeed the case. When my control is shown, I click in the
background space of the FlowLayouPanel which fires the mouse down event and
I set focus. I can then press the numeric keys and everything works great.

If I then click on a child control of the FlowLayoutPanel the focus is lost
and my numeric key events are not handled. I understand why this is
happening, I just don't understand what I can do about it.

I can imagine some hacks that might work but I'm not happy with any of them.
This requirement of mine is something I will need to have in other controls
I plan to create. It's really surprising to me that a Panel doesn't get all
messages! ;0(

If anyone can think of a solution to get my events or messages to always
make it to my FlowLayoutPanel I would really appreciate it.

My ideas for possible solutions are:

1) Anonymous handlers added to each child control that is created. Maybe
for the click event, keyDown, ?? - this handler would first service the
child controls event then set focus to the parent (FlowLayoutPanel). This
is nasty and limited, for example, if I decided to add a control that had
it's own nested control this solution would fail. I could recurse up the
tree until I find the FLP but this is just more nastiness.

I feel like I'm leaving a more elegant solution behind, there must be a way
to do this.

2) .... actually that's all I have right now ;0)

-Steve
Jun 27 '08 #4
Hi Steve,

The easiest way to prevent the checkboxes stealing focus is handling the
GotFocus or Enter event and then programmatically set focus back to the
panel.

In your panel try adding this code

protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);

e.Control.Enter += new EventHandler(Control_Enter);
}

void Control_Enter(object sender, EventArgs e)
{
Focus();
}

If you need to perform some action against the selected 'page' you can just
use the sender reference to determine which page was clicked.

You probably need to

--
Happy Coding!
Morten Wennevik [C# MVP]
"sklett" wrote:
I'm concerned that if I set focus to the *Panel programmatically (per your
suggestion) then if a user clicks on a checkbox control with the mouse the
focus will be removed from the FlowLayoutPanel. Then subsequent 1-9
presses won't be caught by the Panel.

Turns out this is indeed the case. When my control is shown, I click in the
background space of the FlowLayouPanel which fires the mouse down event and
I set focus. I can then press the numeric keys and everything works great.

If I then click on a child control of the FlowLayoutPanel the focus is lost
and my numeric key events are not handled. I understand why this is
happening, I just don't understand what I can do about it.

I can imagine some hacks that might work but I'm not happy with any of them.
This requirement of mine is something I will need to have in other controls
I plan to create. It's really surprising to me that a Panel doesn't get all
messages! ;0(

If anyone can think of a solution to get my events or messages to always
make it to my FlowLayoutPanel I would really appreciate it.

My ideas for possible solutions are:

1) Anonymous handlers added to each child control that is created. Maybe
for the click event, keyDown, ?? - this handler would first service the
child controls event then set focus to the parent (FlowLayoutPanel). This
is nasty and limited, for example, if I decided to add a control that had
it's own nested control this solution would fail. I could recurse up the
tree until I find the FLP but this is just more nastiness.

I feel like I'm leaving a more elegant solution behind, there must be a way
to do this.

2) .... actually that's all I have right now ;0)

-Steve
Jun 27 '08 #5

"Morten Wennevik [C# MVP]" <Mo************@hotmail.comwrote in message
news:59**********************************@microsof t.com...
Hi Steve,

The easiest way to prevent the checkboxes stealing focus is handling the
GotFocus or Enter event and then programmatically set focus back to the
panel.

In your panel try adding this code

protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);

e.Control.Enter += new EventHandler(Control_Enter);
}

void Control_Enter(object sender, EventArgs e)
{
Focus();
}

If you need to perform some action against the selected 'page' you can
just
use the sender reference to determine which page was clicked.

You probably need to

--
Happy Coding!
Morten Wennevik [C# MVP]
Hi Morten,

Thanks again for the continued help! Your suggestion worked very well. I
needed to add a call to Focus() in my control's parent OnShown event and now
it works as I would like it to.

I'm now that much closer to keeping my user's hands OFF the mouse! ;0)

-Steve
Jun 27 '08 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Ramnadh | last post by:
Hi, I am inherting the Panel call and making another class BasePanel By extending all the properties and including some other members as the base for all the classes. After that i am inheriting...
2
by: CJack | last post by:
Hy. I have an MDI form Parent. on run-time it creates a child form Child1. when you press a keyboard button, the Control on Child1 recieves the KeyUp event, which raises the KeyUp event of Child1...
2
by: Jason | last post by:
I have created a 2d isometric game map using tiles and now I'm trying to move around my map..when i go near the edge of the map I want to redraw the map to show new parts of the map however the...
1
by: Ori | last post by:
Hi Guys, Here is my problem, but maybe someone can help me with this. Background: 1. Using C#. 2. I'm having a form which the KeyPreview is on (and must stay like this) and I'm...
1
by: graeme g | last post by:
hi is it possible to catch a keyup event in a panel? as i don't seem to be able to do it... i've even created a message handler for WM_KEYUP in the WndProc procedure but nothing works :-( ...
6
by: | last post by:
Just a general question... When working with a form containing a treeview or similar control... if you need to show different form fields depending on what is selected in the treeview then what...
12
by: Dean Slindee | last post by:
My project has a main form (frmMain, the startup object for the project) and several other "child" forms that are painted within a large panel on frmMain. In each form's Form_Load event, a Weak...
2
by: Linda Liu[MSFT] | last post by:
Hi George, Keyboard input introduces the idea of focus. In Windows, a particular element is designated as having the focus, meaning that it acts as the target for keyboard input. The user sets...
1
by: Chris Jobson | last post by:
>I have a canvas which I use for dragging shapes around such as rectangles Add Focusable="True" to the XAML for the PolyLine and Rectangle elements and then when you set the focus to them they...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.