TranslateTransform vs Canvas Top/Left
Did a little performance testing of Canvas positioning vs TranslateTransform. Turns out Canvas positioning is almost twice as fast.
Its just a single window with code behind. The asterisks stand in for marker symbols that could show Long/Short/Net/Gross is a custom chart.
You can download the code in the PositionPerformance directory of my .Net Demos project on GitHub or below.
MainWindow.xaml
- <Window x:Class="PositionPerformance.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="*" />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <ListBox ItemsSource="{Binding Data}">
- <ListBox.ItemTemplate>
- <DataTemplate>
- <Canvas Width="10" Height="100" >
- <!–<TextBlock Text="*"
- Canvas.Left="{Binding X}"
- Canvas.Top="{Binding Y}" />
- <TextBlock Text="*"
- Canvas.Left="{Binding X1}"
- Canvas.Top="{Binding Y1}" />
- <TextBlock Text="*"
- Canvas.Left="{Binding X2}"
- Canvas.Top="{Binding Y2}" />
- <TextBlock Text="*"
- Canvas.Left="{Binding X3}"
- Canvas.Top="{Binding Y3}" />
- <TextBlock Text="*"
- Canvas.Left="{Binding X4}"
- Canvas.Top="{Binding Y4}" />–>
- <!–<Canvas Width="10" Height="10">–>
- <TextBlock Text="*">
- <TextBlock.RenderTransform>
- <TranslateTransform X="{Binding X}" Y="{Binding Y}" />
- </TextBlock.RenderTransform>
- </TextBlock>
- <TextBlock Text="*">
- <TextBlock.RenderTransform>
- <TranslateTransform X="{Binding X1}" Y="{Binding Y1}" />
- </TextBlock.RenderTransform>
- </TextBlock>
- <TextBlock Text="*">
- <TextBlock.RenderTransform>
- <TranslateTransform X="{Binding X2}" Y="{Binding Y2}" />
- </TextBlock.RenderTransform>
- </TextBlock>
- <TextBlock Text="*">
- <TextBlock.RenderTransform>
- <TranslateTransform X="{Binding X3}" Y="{Binding Y3}" />
- </TextBlock.RenderTransform>
- </TextBlock>
- <TextBlock Text="*">
- <TextBlock.RenderTransform>
- <TranslateTransform X="{Binding X4}" Y="{Binding Y4}" />
- </TextBlock.RenderTransform>
- </TextBlock>
- <TextBlock Text="*">
- <TextBlock.RenderTransform>
- <TranslateTransform X="{Binding X}" Y="{Binding Y}" />
- </TextBlock.RenderTransform>
- </TextBlock>
- <!–</Canvas>–>
- </Canvas>
- </DataTemplate>
- </ListBox.ItemTemplate>
- <ListBox.ItemsPanel>
- <ItemsPanelTemplate>
- <VirtualizingStackPanel Orientation="Horizontal" />
- </ItemsPanelTemplate>
- </ListBox.ItemsPanel>
- </ListBox>
- <StackPanel Grid.Column="1" Margin="10">
- <Button Click="Button_Click">Run</Button>
- <HeaderedContentControl
- Header="WPF Time"
- Content="{Binding ElapsedMilliseconds}"
- TextBlock.TextAlignment="Right"
- />
- <TextBox x:Name="History" />
- </StackPanel>
- </Grid>
- </Window>
MainWindow.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
- using System.Collections.ObjectModel;
- using System.Diagnostics;
- namespace PositionPerformance
- {
- /// <summary>
- /// longeraction logic for MainWindow.xaml
- /// </summary>
- public partial class MainWindow : Window
- {
- public ObservableCollection<Data> Data { get; set; }
- Stopwatch sw = new Stopwatch();
- public MainWindow()
- {
- InitializeComponent();
- DataContext = this;
- Data = new ObservableCollection<Data>();
- }
- public long ElapsedMilliseconds
- {
- get { return (long)GetValue(ElapsedMillisecondsProperty); }
- set {
- SetValue(ElapsedMillisecondsProperty, value);
- this.History.Text += "\n" + ElapsedMilliseconds.ToString();
- }
- }
- // Using a DependencyProperty as the backing store for ElapsedMilliseconds. This enables animation, styling, binding, etc…
- public static readonly DependencyProperty ElapsedMillisecondsProperty =
- DependencyProperty.Register("ElapsedMilliseconds", typeof(long), typeof(MainWindow), new UIPropertyMetadata(0l));
- private void Button_Click(object sender, RoutedEventArgs e)
- {
- Data.Clear();
- var r = new Random();
- foreach (var d in Enumerable.Range(0, 1000).Select(i =>
- new Data() {
- X = r.Next(1, 10), Y = r.Next(1, 100),
- X1 = r.Next(1, 10),
- Y1 = r.Next(1, 100)
- ,
- X2 = r.Next(1, 10),
- Y2 = r.Next(1, 100)
- ,
- X3 = r.Next(1, 10),
- Y3 = r.Next(1, 100)
- ,
- X4 = r.Next(1, 10),
- Y4 = r.Next(1, 100)
- }))
- {
- Data.Add(d);
- }
- sw.Restart();
- Dispatcher.BeginInvoke(new Action(() => ElapsedMilliseconds = sw.ElapsedMilliseconds), System.Windows.Threading.DispatcherPriority.SystemIdle);
- }
- }
- public class Data
- {
- public double X { get; set; }
- public double Y { get; set; }
- public double X1 { get; set; }
- public double Y1 { get; set; }
- public double X2 { get; set; }
- public double Y2 { get; set; }
- public double X3 { get; set; }
- public double Y3 { get; set; }
- public double X4 { get; set; }
- public double Y4 { get; set; }
- }
- }