none
Handle click event on children of Viewport3D

    Question

  •  

    j'ai un viewport3D qui contient des geometriemodel3d ,j'ai besoin d'intersepter l'evenment du click sur les children du viewport3d ,comment je peus faire?SVP c'est urgent

     

    merci d'avance

     

    mon mail :metalomine@hotmail.com

     

    [ed. in english]

    I have a Viewport3D that holds a GeometryModel3d. I need to intercept the click event on the children of the viewport3d, how can I make it work? If you can it is urgent

    Monday, March 24, 2008 5:33 PM

Answers

  • You're in luck. Events in WPF are routed. What this means is that when an element raises an event the event travels up (Bubble) and/or down (Tunnel) the tree between the element and the top level parent. Most of the built-in element events follow the Tunnel then Bubble pattern.

    First every parent of that element is notified that the event is going to fire and has an opportunity to perform an action in response before the event fires. This event travels from the top of the tree and drills to the target element (tunnelling).

    Next every parent is notified that the event has fired. This event travels from the target element up to the top of the tree (bubbling).

     

    There is not a Click event on GeometryModel3D, however you can listen for the MouseDown/MouseUp pair that can be used to act as a click.

     

    So what you want to do is add a handler to the Viewport3D for the Mouse.PreviewMouseDown event (this guarantees that you will see it only when the mouse is depressed within the Viewport3D). You also want to handle the Mouse.PreviewMouseUp event. Basically you set a flag when PreviewMouseDown is firing that informs you the mouse has been depressed within your Viewport. In your PreviewMouseUp handler, you check if that flag is true and handle your logic for a click.

     

    Of course it's more intricate for checking if a SPECIFIC child of the Viewport3D has been clicked but the logic shouldn't be too difficult to figure out (hint use the Source property on the eventArgs parameter).

    Monday, March 24, 2008 6:48 PM
    Moderator
  • To supplement Mike's answer, here's a snippet of code for doing hit-testing on the geometry, so you can tell which GeometryModel3D was clicked.

     

    Code Snippet

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)

    {

    Point position = e.GetPosition(this);

    viewportHitTest(position);

    }

     

    private void viewportHitTest(Point position)

    {

    VisualTreeHelper.HitTest(_viewport, null, HitTestResult,

    new PointHitTestParameters(position));

     

    if (_hitModel != null)

    {

    /* Woo, I have the GeometryModel3D they clicked on */

     

    }

    }

     

    private HitTestResultBehavior HitTestResult(HitTestResult result)

    {

    RayMeshGeometry3DHitTestResult rayHTResult = result as RayMeshGeometry3DHitTestResult;

     

    if (rayHTResult != null)

    {

    _hitModel = rayHTResult.ModelHit as GeometryModel3D;

    return HitTestResultBehavior.Stop;

    }

     

    return HitTestResultBehavior.Continue;

    }

     

     

     

     

    Monday, March 24, 2008 8:00 PM

All replies

  • You're in luck. Events in WPF are routed. What this means is that when an element raises an event the event travels up (Bubble) and/or down (Tunnel) the tree between the element and the top level parent. Most of the built-in element events follow the Tunnel then Bubble pattern.

    First every parent of that element is notified that the event is going to fire and has an opportunity to perform an action in response before the event fires. This event travels from the top of the tree and drills to the target element (tunnelling).

    Next every parent is notified that the event has fired. This event travels from the target element up to the top of the tree (bubbling).

     

    There is not a Click event on GeometryModel3D, however you can listen for the MouseDown/MouseUp pair that can be used to act as a click.

     

    So what you want to do is add a handler to the Viewport3D for the Mouse.PreviewMouseDown event (this guarantees that you will see it only when the mouse is depressed within the Viewport3D). You also want to handle the Mouse.PreviewMouseUp event. Basically you set a flag when PreviewMouseDown is firing that informs you the mouse has been depressed within your Viewport. In your PreviewMouseUp handler, you check if that flag is true and handle your logic for a click.

     

    Of course it's more intricate for checking if a SPECIFIC child of the Viewport3D has been clicked but the logic shouldn't be too difficult to figure out (hint use the Source property on the eventArgs parameter).

    Monday, March 24, 2008 6:48 PM
    Moderator
  • To supplement Mike's answer, here's a snippet of code for doing hit-testing on the geometry, so you can tell which GeometryModel3D was clicked.

     

    Code Snippet

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)

    {

    Point position = e.GetPosition(this);

    viewportHitTest(position);

    }

     

    private void viewportHitTest(Point position)

    {

    VisualTreeHelper.HitTest(_viewport, null, HitTestResult,

    new PointHitTestParameters(position));

     

    if (_hitModel != null)

    {

    /* Woo, I have the GeometryModel3D they clicked on */

     

    }

    }

     

    private HitTestResultBehavior HitTestResult(HitTestResult result)

    {

    RayMeshGeometry3DHitTestResult rayHTResult = result as RayMeshGeometry3DHitTestResult;

     

    if (rayHTResult != null)

    {

    _hitModel = rayHTResult.ModelHit as GeometryModel3D;

    return HitTestResultBehavior.Stop;

    }

     

    return HitTestResultBehavior.Continue;

    }

     

     

     

     

    Monday, March 24, 2008 8:00 PM
  •  

    thanks my friend ,i'll try it .

     

    add to it ,i wanna know how can i know the name of the children 

     

    for exemple :

     

    in XAML code

    ...

    <.....................   x:name="my_children_1".....>

     

     

    so when i intercept the event of the mouse (preveious) ,how can i know wich one is clicked?

     

    may be is stupide to ask ,but really i hade a probléme :

     

    more details :

     

     

    private void viewportHitTest(Point position)

    {

    VisualTreeHelper.HitTest(_viewport, null, HitTestResult,

    new PointHitTestParameters(position));

     

    if (_hitModel != null)

    {

    _hitModel.DependencyObject.name // this one show the type of the model

     

    so i need too show or to know the name of the model (my_children_1 for exemple)

     

    }

    }

     

    thanks

    Monday, March 24, 2008 8:45 PM
  • Hmm.  Why not just make a dependancy property and identify that way?

     

    For instance:

     

    myModel.SetValue(MyDepProp, myDataTag);

     

    and use the GetValue on the _hitModel.

     

    If you want to set the name for your objects in code, maybe for animation purposes, you can use the NameScope.GetNameScope() static function.

     

    -Jer

     

    Monday, March 24, 2008 10:17 PM
  • Hai,

         I need to find a particular location in the 3d object where i want to click.

        I have loaded an xaml file in WPF application having positions and indices. Now i want to click a particular position in the object and for every click there should be an event.. Is it possible?

        Also is it possible to give animation effects to particular position in that 3d object?

    Regards,
    Anitha.N
    Wednesday, June 25, 2008 9:26 AM