I've placed a bunch of elements on a WPF canvas within an ItemsControl + datatemplate. They all have X and Y coordinates. They also move around. I loop through the elements and I add or minus a certain amount from their X and/or Y coordinate(s).
Sounded easy enough to pull of. It kinda works. Problem is that every element seems to have a different idea of what Y means.
If the elements touch the sides of the canvas, they should bounce back. It works for all sides except for the bottom side. I've defined the bottom at Y 400 so they should never pass this. They all seem to have a different idea of what Y 400 means.
This means that they all bounce back at a different moment from the bottom.
<Canvas x:Name="Canvas" Background="LightGray" Grid.Row="0" Grid.Column="0" Width="800" Height="600">
<ItemsControl x:Name="SpaceObjectsIC"
ItemsSource="{Binding SpaceObjects, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Fill="{Binding Color, Converter={StaticResource ColorConverter}}"
Height="{Binding Radius}" Width="{Binding Radius}" Tag="{Binding Name}"
ClipToBounds="True">
<Ellipse.RenderTransform>
<TranslateTransform X="{Binding X}" Y="{Binding Y}" />
</Ellipse.RenderTransform>
</Ellipse>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
This is the move method thats part of the spaceobject class. Every element on the canvas uses this method to move + check if they hit the side of the canvas. For some of the elements the 400 which I defined as the bottom of the canvas works. For most it doesn't.
X and Y are decimal coordinates of the element. _vx and _vy are the amount that they move in either an X or Y direction. Both decimal. Used to be float and I also tried double, but none of them changed the outcome.
public void Move()
{
X += _vx;
Y += _vy;
int newRad = (int) Radius;
// leftside canvas
if (X < -10 + newRad)
{
_vx = Math.Abs(_vx);
Color = Color.Brown;
}
// rightside canvas
if (X > 770 - newRad)
{
_vx = -Vx;
Color = Color.Blue;
}
// topside canvas
if (Y < 0 + newRad)
{
_vy = Math.Abs(_vy);
Color = Color.Pink;
}
// bottomside canvas
if (Y > 400 - newRad)
{
_vy = -_vy;
Color = Color.Orange;
}
}
If more code is needed let me know, but there is not much more code than this. Only thing I did before this was creating the elements. Just a bunch of decimals that had to be set.
In this picture you see tree point. On the left as8, and on the right as20 and as21. On the right hand side of the screen you can see the X and the Y of these elements (x on top, Y below).
As you can see as8 is right between as20 and as21, so it's Y coordinate should be between 300 and 312. However, it's way higher!
Full xaml
<Page x:Class="Flat_space.View.Pages.Space.Space"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Flat_space.View.Pages.Space"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:converters="clr-namespace:Flat_space.Converters"
mc:Ignorable="d"
Title="Space"
DataContext="{Binding Space, Source={StaticResource Locator}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadSpaceCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Page.Resources>
<converters:ColorConverter x:Key="ColorConverter" />
<converters:BoolToEnabledConverter x:Key="BoolToEnabledConverter" />
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="7*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Canvas x:Name="Canvas" Background="LightGray" Grid.Row="0" Grid.Column="0" Width="800" Height="600">
<ItemsControl x:Name="SpaceObjectsIC"
ItemsSource="{Binding SpaceObjects, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Fill="{Binding Color, Converter={StaticResource ColorConverter}}"
Height="{Binding Radius}" Width="{Binding Radius}" Tag="{Binding Name}"
ClipToBounds="True">
<Ellipse.RenderTransform>
<TranslateTransform X="{Binding X}" Y="{Binding Y}" />
</Ellipse.RenderTransform>
</Ellipse>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.ColumnSpan="3"
Grid.Column="0"
Orientation="Vertical">
<TextBlock Foreground="Green" Text="{Binding SimulationState, NotifyOnSourceUpdated=True}" />
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.ColumnSpan="3"
Orientation="Horizontal">
<Button Command="{Binding BackToMainMenuCommand}" Margin="0,0,5,0">Back To Main Menu</Button>
<Button>Back 5 Seconds</Button>
<Button x:Name="StartButton" Command="{Binding StartCommand}" Margin="5,0,5,0">Start</Button>
<Button x:Name="StopButton" Command="{Binding StopCommand}" Margin="5,0,5,0">Stop</Button>
<Button>Forward 5 Seconds</Button>
<Button Command="{Binding SpaceDetailsCommand}">Data details</Button>
</StackPanel>
</StackPanel>
</Grid>
</Page>