Adding objects in code

Jan 3, 2010 at 5:33 PM

It seems that there exist a problem of creating instances of objects in code.

I have made an object in blend as a user control and placed in the scene. Now everything is ok. The object created is acting as it should.

But when i try to make an instance of this user control from within code i get :

Error: Unhandled Error in Silverlight Application Could not determine the outline of UIElement sprite_1. Could not find a point within its boundaries....

If i use a rectangle as shape for the user control it works, but anything else fails with the error mentioned above.

I have also tried to group the shape together with a canvas and set the physics behavior to the canvas with no luck.

To be able to make the most out of this one have to be able to make instances of objects in code.

Anybody ?

Tommy,

 

Coordinator
Jan 3, 2010 at 9:18 PM

The problem is that the boundary detection algorithm uses VisualTreeHelper.FindElementsInHostCoordinates - and this method requires that the object is visible on the Canvas before a HitTest can be performed.

You can get around this a couple of ways; (1) have at least one instance of your UserControl on the screen when the Physics Controller Initializes (that is, when your app starts up); or (2) Introduce a short (10 ms or so) delay between the time that your UserControl is added into the Canvas, and the Physics Behaviors are added in. You can use a Storyboard for this.

There is a bit more info here -  http://physicshelper.codeplex.com/Thread/View.aspx?ThreadId=77450

Jan 3, 2010 at 10:45 PM

thanks for your replay.

My first instance of the object is the one made in blend, ok.

It shows up, and have the right behavior. I have made a button like the rag doll example to add another instance of the object but i still can't make it to behave like the first instance made in blend.

Is it something i am missing here ?

Tommy,

Norway

Coordinator
Jan 3, 2010 at 11:08 PM
Edited Jan 3, 2010 at 11:10 PM

[oops, I edited this to correct the method name and demo]

In your button click event, do you call AddPhysicsBodyForCanvasWithBehaviors on the physics Controller? (if you look at the DemoBehaviors2 (Rag Doll) sample, you can see the full code)

                _physicsController.AddPhysicsBodyForCanvasWithBehaviors(_ucRagDollNew.LayoutRoot);

Jan 4, 2010 at 5:45 PM
Edited Jan 4, 2010 at 6:13 PM

Thanks for trying to solve this issue.

Source code:

public partial class MainPage : UserControl
    {

        UserControl2 r;
        PhysicsControllerMain _physicsController;
        Random _rand = new Random();
        public MainPage()
        {
            // Required to initialize variables
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            _physicsController = LayoutRoot.GetValue(PhysicsControllerMain.PhysicsControllerProperty) as PhysicsControllerMain;
            if (_physicsController == null)
            {
                MessageBox.Show("null");
            }
        
        
        }

        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            r = null;
            r = new UserControl2();

         LayoutRoot.Children.Add(r);

                r.SetValue(Canvas.LeftProperty, Convert.ToDouble(_rand.Next(0, 500)));
                r.SetValue(Canvas.TopProperty, 0D);

                _physicsController.AddPhysicsBodyForCanvasWithBehaviors(r.LayoutRoot);

                r = null;
           
        }
    }

This is how you do it in the sample code(almost :))

The first object of this temporary r(made in Blend) is working properly and have the correct physic behavior.

Usercontrol2
  LayoutRoot
     Canvas
       PhysicsObjectBehavior
       Rectangle

 

A rectangle wont even work her(except for the first made in Blend), but with this :

Usercontrol2
  LayoutRoot
    Rectangle
    PhysicsObjectBehavior

it works, but only for rectangles. I would be happy to solve this :)

Tommy,

Norway

Coordinator
Jan 4, 2010 at 6:17 PM

Would it be possible for you to send me a ZIP of your sample project?  You could use the contact user form from my profile page here -

http://www.codeplex.com/site/users/view/AndyBeaulieu

 

Jan 4, 2010 at 6:32 PM

Hi,

Download it from here :

http://www.stromhaug.no/tommy/SilverlightApplication9.zip

 

Coordinator
Jan 4, 2010 at 9:26 PM

Ok, the problem is that the boundary caching mechanism is dependant on the Physics Object having a name (it uses this in a Dictionary to lookup up subsequently added items).

I'll look at cleaning up this along with some other things in the next update.

But for now, just add an x:Name to your Canvas inside the UserControl2:

<Canvas x:Name="LayoutRoot">
  <Canvas x:Name="cnvAlien" Height="35" Width="34" Canvas.Left="19" Canvas.Top="17">
   <i:Interaction.Behaviors>
    <pb:PhysicsObjectBehavior/>
   </i:Interaction.Behaviors>
   <Ellipse Fill="#FF9F4343" Stroke="Black" Height="35" Width="34"/>
  </Canvas>
 </Canvas>

Jan 6, 2010 at 8:51 PM

Thank you sir! Fixed my problem :)

 

Tommy,

Norway