Cyral
Cyral

Reputation: 14153

Scale the position of child elements, but not their size?

I am implementing behavior in my application that will resize the main content area depending on the screen size. (The content area is made up of icons and other elements that the user can place/draw)

Currently, the margin property is used to position elements using a converter that converts a Point to Thickness.

Example:

https://i.sstatic.net/6kg4o.png

I need to "scale" the child elements position to the size of the container. The position of the elements is all that needs to be scaled, not the size.

How can I apply a transform (RenderTransform or LayoutTransform) to all child elements of a grid, so that the icon positions will scale to the correct position depending on the grid size?

It should also be noted that these icons may be removed/added while the application is running.

Upvotes: 3

Views: 1228

Answers (1)

heltonbiker
heltonbiker

Reputation: 27575

I have already done this before, and I would suggest you to do this:

  1. In your element class (say, Circle), you have some sort of coordinate representing their position, proportionally to the size of the container. So, 0.5 would represent the middle, 0.33 would represent one third to the left, etc.
  2. Create an IMultiValueConverter that calculates the pixel coordinate based on the relative coordinate and the container size along a given dimension;
  3. Declare your object in XAML with its margins (in case of a Grid container) or Canvas.Top/Left (in case of a Canvas container) in the following way:

Xaml:

<Circle>
    <Circle.Margin>
        <MultiBinding Converter="{StaticResource ThatConverter}">
            <Binding ElementName="container" Path="ActualWidth"/>
            <Binding Path="CircleCoordinateX"/>
            <!-- The same for height and Y coordinate -->
        </MultiBinding>
    </Circle.Margin>
</Circle>

Instead of this more simplistic approach, ideally you should make your container to be an ItemsControl, create an ItemsTemplate for datatype Circle, and bind the container ItemsSource to some ObservableCollection on some viewmodel, for example.

Upvotes: 2

Related Questions