Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > Avalon

Vista - Hit testing and moving shapes

 
 
Old 01-10-2006   #1 (permalink)
Peter Johnston


 
 

Hit testing and moving shapes

Below is some extracted code I was playing around with to move a Shapes on a
canvas.
I'm using MouseLeftButtonDown to select a Shape type, MouseMove to move the
selected
Shape, and MouseLeftButtonUp to release the selected Shape. A few questions:

1. The select on mouse down uses InputHitTest on the mainCanvas object. I've
also
seen VisualTreeHelper.HitTest (was VisualOperations) been used in example
code. Is
there any reason for preferring one over the other? Is there a "best" way of
doing
this sort of operation? And how would you do it for Geometry types, which
don't derive from FrameworkElement?

2. Movement seems fine, if a little CPU intensive (this is on a ATI9800,
tier 2
graphics card). However, if I move the mouse very fast, it "loses" the
selected
object. Any reason why this is happening?

3. In the MouseMove event, in the "if" statement, there's a type selector,
"this.selected is Shape". This works for all Shape types of this.selected.
If
however, I put "this.selected.GetType() == typeof( Shape )", it doesn't
work, but putting "Rectangle", for example, instead of "Shape" will - for
Rectangles only of course. Has my understanding of types gone haywire!?

...
private FrameworkElement selected;
private Point startPoint;
private Point elementStartPoint;
...
void mainCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
this.selected = null;
}

void mainCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition( (UIElement)sender );

// Below is short form of
// IInputElement baseElement = mainCanvas.InputHitTest( startPoint );
// this.selected = baseElement as FrameworkElement;

this.selected = mainCanvas.InputHitTest( startPoint ) as FrameworkElement;

this.elementStartPoint.Y = Canvas.GetTop( this.selected );
this.elementStartPoint.X = Canvas.GetLeft( this.selected );
}

void mainCanvas_MouseMove(object sender, MouseEventArgs e)
{
Point pt = e.GetPosition((UIElement)sender);

if ( this.selected != null && this.selected is Shape )
{
Canvas.SetTop( this.selected, this.elementStartPoint.Y + ( pt.Y -
this.startPoint.Y ) );
Canvas.SetLeft( this.selected, this.elementStartPoint.X + ( pt.X -
this.startPoint.X ) );
}
}
...



My System SpecsSystem Spec
Old 01-10-2006   #2 (permalink)
Philippe Lavoie


 
 

Re: Hit testing and moving shapes

Peter Johnston wrote:
> Below is some extracted code I was playing around with to move a Shapes on a
> canvas.
> I'm using MouseLeftButtonDown to select a Shape type, MouseMove to move the
> selected
> Shape, and MouseLeftButtonUp to release the selected Shape. A few questions:
>
> 3. In the MouseMove event, in the "if" statement, there's a type selector,
> "this.selected is Shape". This works for all Shape types of this.selected.
> If
> however, I put "this.selected.GetType() == typeof( Shape )", it doesn't
> work, but putting "Rectangle", for example, instead of "Shape" will - for
> Rectangles only of course. Has my understanding of types gone haywire!?
>


The 'is' operator will respect the inheritance. In your example, a
Rectangle is a Shape so it will work fine. However, doing a GetType
returns you the current type of the instance hence why you need to
specify Rectangle.

I hope this helps.

Phil
My System SpecsSystem Spec
Old 01-10-2006   #3 (permalink)
CSkinner


 
 

Re: Hit testing and moving shapes

You may want to capture the mouse in the down and release it in the mouse
up. I've got very similar code and have never seen the selected element get
"lost" regardless of how fast I move the mouse. Just a thought.

CS


"Peter Johnston" <nospam@nospam.com> wrote in message
news:e6EXBUK$FHA.3804@TK2MSFTNGP14.phx.gbl...
> Below is some extracted code I was playing around with to move a Shapes on
> a canvas.
> I'm using MouseLeftButtonDown to select a Shape type, MouseMove to move
> the selected
> Shape, and MouseLeftButtonUp to release the selected Shape. A few
> questions:
>
> 1. The select on mouse down uses InputHitTest on the mainCanvas object.
> I've also
> seen VisualTreeHelper.HitTest (was VisualOperations) been used in example
> code. Is
> there any reason for preferring one over the other? Is there a "best" way
> of doing
> this sort of operation? And how would you do it for Geometry types, which
> don't derive from FrameworkElement?
>
> 2. Movement seems fine, if a little CPU intensive (this is on a ATI9800,
> tier 2
> graphics card). However, if I move the mouse very fast, it "loses" the
> selected
> object. Any reason why this is happening?
>
> 3. In the MouseMove event, in the "if" statement, there's a type selector,
> "this.selected is Shape". This works for all Shape types of this.selected.
> If
> however, I put "this.selected.GetType() == typeof( Shape )", it doesn't
> work, but putting "Rectangle", for example, instead of "Shape" will - for
> Rectangles only of course. Has my understanding of types gone haywire!?
>
> ...
> private FrameworkElement selected;
> private Point startPoint;
> private Point elementStartPoint;
> ...
> void mainCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
> {
> this.selected = null;
> }
>
> void mainCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
> {
> startPoint = e.GetPosition( (UIElement)sender );
>
> // Below is short form of
> // IInputElement baseElement = mainCanvas.InputHitTest( startPoint );
> // this.selected = baseElement as FrameworkElement;
>
> this.selected = mainCanvas.InputHitTest( startPoint ) as
> FrameworkElement;
>
> this.elementStartPoint.Y = Canvas.GetTop( this.selected );
> this.elementStartPoint.X = Canvas.GetLeft( this.selected );
> }
>
> void mainCanvas_MouseMove(object sender, MouseEventArgs e)
> {
> Point pt = e.GetPosition((UIElement)sender);
>
> if ( this.selected != null && this.selected is Shape )
> {
> Canvas.SetTop( this.selected, this.elementStartPoint.Y + ( pt.Y -
> this.startPoint.Y ) );
> Canvas.SetLeft( this.selected, this.elementStartPoint.X + ( pt.X -
> this.startPoint.X ) );
> }
> }
> ...
>
>



My System SpecsSystem Spec
Old 01-10-2006   #4 (permalink)
Nick Kramer [MSFT]


 
 

Re: Hit testing and moving shapes

InputHitTest adds input policy to VisualTreeHelper.HitTest, including paying
attention to the Enabled and I****TestVisible properties.

I'm not sure what you mean by "losing" the element. But keep in mind that
just like Win32, WPF will coalesce consecutive MouseMove events. If you
haven't processed the last mouse move event when this next one comes in,
they will be combined into a single event.

-Nick Kramer [MSFT]
http://blogs.msdn.com/nickkramer

---
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm


"Peter Johnston" <nospam@nospam.com> wrote in message
news:e6EXBUK$FHA.3804@TK2MSFTNGP14.phx.gbl...
> Below is some extracted code I was playing around with to move a Shapes on
> a canvas.
> I'm using MouseLeftButtonDown to select a Shape type, MouseMove to move
> the selected
> Shape, and MouseLeftButtonUp to release the selected Shape. A few
> questions:
>
> 1. The select on mouse down uses InputHitTest on the mainCanvas object.
> I've also
> seen VisualTreeHelper.HitTest (was VisualOperations) been used in example
> code. Is
> there any reason for preferring one over the other? Is there a "best" way
> of doing
> this sort of operation? And how would you do it for Geometry types, which
> don't derive from FrameworkElement?
>
> 2. Movement seems fine, if a little CPU intensive (this is on a ATI9800,
> tier 2
> graphics card). However, if I move the mouse very fast, it "loses" the
> selected
> object. Any reason why this is happening?
>
> 3. In the MouseMove event, in the "if" statement, there's a type selector,
> "this.selected is Shape". This works for all Shape types of this.selected.
> If
> however, I put "this.selected.GetType() == typeof( Shape )", it doesn't
> work, but putting "Rectangle", for example, instead of "Shape" will - for
> Rectangles only of course. Has my understanding of types gone haywire!?
>
> ...
> private FrameworkElement selected;
> private Point startPoint;
> private Point elementStartPoint;
> ...
> void mainCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
> {
> this.selected = null;
> }
>
> void mainCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
> {
> startPoint = e.GetPosition( (UIElement)sender );
>
> // Below is short form of
> // IInputElement baseElement = mainCanvas.InputHitTest( startPoint );
> // this.selected = baseElement as FrameworkElement;
>
> this.selected = mainCanvas.InputHitTest( startPoint ) as
> FrameworkElement;
>
> this.elementStartPoint.Y = Canvas.GetTop( this.selected );
> this.elementStartPoint.X = Canvas.GetLeft( this.selected );
> }
>
> void mainCanvas_MouseMove(object sender, MouseEventArgs e)
> {
> Point pt = e.GetPosition((UIElement)sender);
>
> if ( this.selected != null && this.selected is Shape )
> {
> Canvas.SetTop( this.selected, this.elementStartPoint.Y + ( pt.Y -
> this.startPoint.Y ) );
> Canvas.SetLeft( this.selected, this.elementStartPoint.X + ( pt.X -
> this.startPoint.X ) );
> }
> }
> ...
>
>



My System SpecsSystem Spec
Old 01-10-2006   #5 (permalink)
Peter Johnston


 
 

Re: Hit testing and moving shapes

"Nick Kramer [MSFT]" <nkramer@ms.spam> wrote in message
news:Oqqn5Tp$FHA.208@tk2msftngp13.phx.gbl...
> I'm not sure what you mean by "losing" the element. But keep in mind that
> just like Win32, WPF will coalesce consecutive MouseMove events. If you
> haven't processed the last mouse move event when this next one comes in,
> they will be combined into a single event.


Thanks for all the answers.

By losing, I mean when the mouse if moved fast, the pointer moves on, but
the
object selected stops. Of course, having thought about it, as the mouse
events are
applied to the canvas only, the mouse is moving out of the canvas, so the
events
no longer apply - although the object stops within the canvas, not at the
edge,
just to be clear*. Perhaps, as CS points out, I need to capture the mouse
(tonight's
homework I also found the SDK article on visual-layer hit-testing, which
should
help.

Peter Johnston
* The mouse is a high-precision optical (Logitech MX500).


My System SpecsSystem Spec
 

Thread Tools


Similar Threads
Thread Forum
First Look: Windows 7 Shapes Up as Microsoft’s Best OS Yet Vista News
How to export Visio shapes and text to txt or excel file? .NET General
grouping shapes with lines inside Vista General
Vista or Publisher2007? Filling shapes... Vista print fax & scan


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

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