Resizing user controls

Mar 30, 2010 at 6:52 PM

Does resizing a physics-enabled user control resize the corresponding GeometryObject?

For example, take this user control:

<UserControl x:Class="PhoneRecognizer.circleControl"
    mc:Ignorable="d" d:DesignHeight="50" d:DesignWidth="50" Background="Yellow">
    <Canvas x:Name="LayoutRoot" Background="Aqua">

        <Ellipse x:Name="circleGraph" Height="50" Width="50">
                <!-- <ImageBrush ImageSource="ball.png" Stretch="Fill" /> -->
                <RadialGradientBrush RadiusX="0.192" RadiusY="0.167" Center="0.346,0.281" GradientOrigin="0.346,0.281">
                    <GradientStop Color="#FF84D49D" Offset="0"/>
                    <GradientStop Color="#FF397E4F" Offset="1"/>
                <pb:PhysicsObjectBehavior RestitutionCoefficient="1.0"   />

If I add the control to an existing Canvas (e.g., via XAML --> <local:circleControl x:Name="control1"></local:circleControl>) w/o resizing any of the control's elements (the user control, the canvas or the ellipse), I end up with a well-behaved physics-enabled ellipse. But, if I add a second control via code and resize it - and I've tried about every combination of control, canvas, and ellipse I can think of - the visual control is drawn at the correct size, but the geometry object - which I believe I'm seeing by setting the parent canvas's PhysicsContollerBehavior's Debug property to True - appears to be the size of the "vanilla" user control and is positioned in the upper-left corner of the visual control. Is size cached based on the initial "vanilla" user control's size.

Any way to adjust this? I tried programmatically resetting the geometry object via a call to the Farseer engine's Geometry factory, but it doesn't look like it's having an impact.

Mar 30, 2010 at 7:15 PM

I would give this a go:

Put your PhysicsObjectBehavior on the container Canvas instead of the Ellipse itself. Resize the Ellipse inside the Canvas. Make sure that the Width and Height of the Canvas is big enough to cover the adjusted Ellipse height and width.

Mar 12, 2011 at 7:59 AM

@Andy: i've tried to put an ellipse inside a canvas and resize the ellipse at runtime but it doesnt update the fixturelist of its sprite. am i missing something?

Mar 25, 2011 at 4:02 PM

Hi crossguard,

I ran into similar problems. First of all: the green debug overlay is not correctly positioned (it took me a while to notice that). It always shows off in the upper-left corner with initial UI-Size. I managed to bring it into the correct position - but the size still does not reflect the Body-Object's size.

Second: I solved the resizing issue by doing the following. I am using a dedicated Boundary-element by the way.

//create new body
var body = BodyFactory.CreateBody(Sprite.Simulator, Sprite.BodyObject.Position, this);

//resize the sprite to have the boundary element in correct size and position
Sprite.Height = ActualHeight;
Sprite.Width = ActualWidth;
//create shape from boundaryElement
List<FarseerPhysics.Collision.Shapes.Shape> shapes = boundaryHelper.CreateShapesFromElement(Sprite.Simulator, physicsBackdrop as FrameworkElement);
//create new fixtures (should only be one in my case though)
foreach (FarseerPhysics.Collision.Shapes.Shape shape in shapes) {
    var fixture = body.CreateFixture(shape, Sprite.Name);
    try {
        // restore collision categories and stuff
var filter = fixture.CollisionFilter; filter.RemoveCollidesWithCategory(Category.Cat10); } catch (InvalidOperationException) { } fixture.Restitution = .5f; } // copy over all data from old body body.AngularDamping = Sprite.BodyObject.AngularDamping; //... body.UserData = Sprite.BodyObject.UserData; Sprite.Simulator.RemoveBody(Sprite.BodyObject); Sprite.BodyObject = body;

This works like a charm for me.