multiple panels mouse movements similar functiionality but different datasets.

J

jleslie48

I made a panel and a make a plot of a data set in it. I created
mouse buttons to zoom in and out, etc and they all work fine.

I now want to make a duplicate of that panel, WITH ALL of the
programmed buttons.

when I made the cut and paste of the panel1 I got a panel2 but all my
functions were not duplicated:

////////////////////////////////////////////////////////////////////////////////////////////////


private void panel1_MouseDown(object sender,MouseEventArgs e) {

if (e.Button== MouseButtons.Left) {
md_e = mm_e = e;

draw_crosshairs = true;
panel1.Invalidate();
}//then left
else {
md_e_right =mm_e = e;
}//then right
}//panel1_mousedown

private void panel1_MouseMove(object sender,MouseEventArgs e) {
mm_e = e;
if (e.Button== MouseButtons.Left) {
draw_marker = false;

if (draw_crosshairs) {
panel1.Invalidate(); //this will force the
crosshairs to be
}//then //drawn at the mouse pointer
location.
}//then left
}//panel1_MouseMove

private void panel1_MouseUp(object sender,MouseEventArgs e) {
....

} //panel1_MouseUp


//////////////////////////////////////////////////////////////////////////////////////////////

now I know I can make a

private void panel2_MouseUp ...
private void panel2_MouseDown...
private void panel2_MouseMove...

etc cut and paste the code, and change the variables, but that
doesn't seem right.

how do I go about using a generic set of say panelx_MouseUp...

where the x is the specific panel I want (panel1, panel2,
panel3,....)

Tia,

Jon
 
J

jleslie48

[...]
now I know I can make a
private void panel2_MouseUp ...
private void panel2_MouseDown...
private void panel2_MouseMove...
etc  cut and paste the code, and change the variables,  but that
doesn't seem right.
how do I go about using a generic set of say panelx_MouseUp...
where the x is the specific panel I want (panel1, panel2,
panel3,....)

In general the idea is, as you say, to avoid copying and pasting code,
of course.  This is generally done in a couple of basic ways: abstract
the functionality into its own class and reuse the class, or
parameterize the functionality and pass appropriate parameters to the code.

To apply that here, the first approach would involve creating a new
sub-class of the System.Windows.Forms.Panel class, and put the
functionality you desire into that class.  Then just put an instance of
that sub-class wherever you want a panel that behaves in that way.

The second approach would be to associate specific data with specific
panels, use the same event handlers for each instance of Panel you have,
but use the per-panel specific data in the event handler.  A common way
of doing this is to store something in the Tag property of the Panel
(initialized, for example, in your Form sub-class's constructor), and
then retrieving that data in the event handler (by casting the "sender"
object to Control and accessing the Tag property).

Depending on why you choose Panel in the first place, it may well be
that it makes more sense to go the sub-class route.  It's a bit more
work up front, but unless there's something about the Panel class itself
that you really need (e.g. scrolling contents), it probably makes more
sense from an architectural point of view to simply subclass
System.Windows.Forms.Control instead of the Panel class, and put the
per-instance specific data in that Control sub-class.

Pete

thanks pete,

I am interested in the sub class method but my own banging around I
stumbled on the retrieving the sender object:

private void panel1_MouseDown(object sender,MouseEventArgs e) {


indx_type local_data_index
=((WindowsFormsApplication01.myPlotPanel)(sender)).data_index ;
ok, here here are this is ugly we need a better way to get
sender variables

writeln_output02("panel is :" + local_data_index
+ "data for this panel is :" +
dataname[local_data_index] );


I can live with the sender to get me at least functional and while my
users are playing I can explore the sub class.
my only issue/complaint is the syntax:

(WindowsFormsApplication01.myPlotPanel)(sender)).data_field

shoudn't I be able to use some form of "using" so that I don't have to
type the
"(WindowsFormsApplication01.myPlotPanel)(sender))." part
for unique "data_field" variables?
 
J

jleslie48

[...]
I can live with the sender to get me at least functional and while my
users are playing I can explore the sub class.
my only issue/complaint is the syntax:
(WindowsFormsApplication01.myPlotPanel)(sender)).data_field

shoudn't I be able to use some form of "using" so that I don't have to
type the
"(WindowsFormsApplication01.myPlotPanel)(sender))."  part
for unique "data_field" variables?

No.  The "using" statement is for objects that implement IDisposable, to
ensure that they are disposed of when the variable goes out of scope.

But, you can always store the result of the cast in a variable and use that.

Also, if you are sub-classing the Panel class, then I would recommend
not subscribing to the event, but rather just overriding the method that
raises it.  Then you wind up not needing the cast at all, because the
sender is always "this".

So your code would look more like this:

   protected override void OnMouseDown(MouseEventArgs e)
   {
     writeln_output02("panel is :" + data_index +
       "data for this panel is :"  + dataname[data_index] );
   }

Note the class member "data_index" simply being used directly.

Pete

thanks again Pete.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top