title: Best coding approach to scroll long text and images horizontally in WPF/XAML?
body: <blockquote>
    <p><strong>Possible Duplicate:</strong><br>
    <a href="https://stackoverflow.com/questions/3002271/smooth-text-animation-marquee-using-wpf">Smooth text animation (Marquee) using WPF</a>  </p>
  </blockquote>
  
  
  
  <p>I am just wondering if there is some <strong>best coding approach</strong> <strong><em>to scroll</em></strong> text and images horizontally in WPF?</p>
  
  <p>Basically I used some code to do it like </p>
  
  <pre><code>        private void PopulateCanvas()
                  {
  
                      canvas1.Width = RootGrid.ActualWidth;
                      canvas1.Height = RootGrid.ActualHeight;
  
                      foreach (var item in PluginContentItems)
                      {
                          if (IsImage(item.IPluginContentItemElements))
                          {
                              string imageName = GetImageName(item.IPluginContentItemElements);
  
                              if (IsGifImage(item.IPluginContentItemElements))
                                  AddGIFImage(imageName);
                              else
                                  AddImage(imageName);
                          }
                          else // Text
                          {
                              string text = GetText(item.IPluginContentItemElements);
                              SolidColorBrush brush = GetFontColor(item.IPluginContentItemElements);
                              AddTextBlock(text, brush);
                          }
                      }
  
                      canvas1.Dispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(Object state)
                      {
                          var node = textBlocks.First;
  
                          while (node != null)
                          {
                              if (node.Previous != null)
                              {
                                  if (node.Previous.Value.GetType().FullName.Contains("TextBlock"))
                                      Canvas.SetLeft(node.Value, Canvas.GetLeft((TextBlock)node.Previous.Value) + ((TextBlock)node.Previous.Value).ActualWidth); // + gap
                                  else if (node.Previous.Value.GetType().FullName.Contains("GifImage"))
                                      Canvas.SetLeft(node.Value, Canvas.GetLeft((GifImage)node.Previous.Value) + ((GifImage)node.Previous.Value).ActualWidth); // + gap
                                  else if (node.Previous.Value.GetType().FullName.Contains("Controls.Image"))
                                      Canvas.SetLeft(node.Value, Canvas.GetLeft((Image)node.Previous.Value) + ((Image)node.Previous.Value).ActualWidth); // + gap
                              }
                              else
                              {
                                  if (node.Value.GetType().FullName.Contains("TextBlock"))
                                      Canvas.SetLeft((TextBlock)node.Value, canvas1.Width); // + gap
                                  if (node.Value.GetType().FullName.Contains("Image"))
                                      Canvas.SetLeft((Image)node.Value, canvas1.Width); // + gap
                                  if (node.Value.GetType().FullName.Contains("GifImage"))
                                      Canvas.SetLeft((GifImage)node.Value, canvas1.Width); // + gap
                              }
  
                              node = node.Next;
                          }
  
                          return null;
  
                      }), null);
  
                  }
  
  
       void timer_Elapsed(object sender, ElapsedEventArgs e)
              {
                  canvas1.Dispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(Object state)
                  {
                      var node = textBlocks.First;
                      var lastNode = textBlocks.Last;
  
                      while (node != null)
                      {
                          double newLeft = Canvas.GetLeft(node.Value) - move_amount;
  
                          double w1 = 0;
  
                          if (node.Value is TextBlock)
                              w1 = ((TextBlock)node.Value).ActualWidth;
  
                          if (node.Value is Image)
                              w1 = ((Image)node.Value).ActualWidth;
  
                          if (node.Value is GifImage)
                              w1 = ((GifImage)node.Value).ActualWidth;
  
                          if (newLeft &lt; (0 - w1)) // + gap
                          {
                              textBlocks.Remove(node);
  
                              var lastNodeLeftPos = Canvas.GetLeft(lastNode.Value);
  
                              textBlocks.AddLast(node);
  
                              if (lastNode.Value.GetType().FullName.Contains("TextBlock"))
                              {
                                  // + gap
                                  if ((lastNodeLeftPos + ((TextBlock)lastNode.Value).ActualWidth) &gt; canvas1.Width) // Last element is offscreen
                                      newLeft = lastNodeLeftPos + ((TextBlock)lastNode.Value).ActualWidth; // + gap
                                  else
                                      newLeft = canvas1.Width; //  +gap;
                              }
                              else if (lastNode.Value.GetType().FullName.Contains("GifImage"))
                              { // + gap
                                  if ((lastNodeLeftPos + ((GifImage)lastNode.Value).ActualWidth) &gt; canvas1.Width) // Last element is offscreen
                                      newLeft = lastNodeLeftPos + ((GifImage)lastNode.Value).ActualWidth; // + gap
                                  else
                                      newLeft = canvas1.Width; // + gap
                              }
                              else if (lastNode.Value.GetType().FullName.Contains("Controls.Image"))
                              { // + gap
                                  if ((lastNodeLeftPos + ((Image)lastNode.Value).ActualWidth) &gt; canvas1.Width) // Last element is offscreen
                                      newLeft = lastNodeLeftPos + ((Image)lastNode.Value).ActualWidth; // + gap
                                  else
                                      newLeft = canvas1.Width; // + gap
                              }
                          }
  
                          Canvas.SetLeft(node.Value, newLeft);
  
                          node = node == lastNode ? null : node.Next;
                      }
  
                      return null;
  
                  }), null);
              }
  
  
  private void AddGIFImage(string file)
          {
              try
              {
                  string pathToImage = System.IO.Path.Combine(Settings.ContentFolderPath, file);
  
                  Uri u = new Uri(pathToImage);
                  GifImage gif = new GifImage(u);
                  gif.Height = canvas1.Height; //  canvas1.Height / koeffImage;
                  canvas1.Children.Add(gif);
                  Canvas.SetTop(gif, 0);
                  Canvas.SetLeft(gif, -999);
                  textBlocks.AddLast(gif);
              }
              catch (Exception ex)
              {
                  HasError = true;
                  ErrorMessage = ex.Message;
              }
          }
  
          private void AddImage(string file)
          {
              try
              {
                  string pathToImage = System.IO.Path.Combine(Settings.ContentFolderPath, file);
  
                  Image image = new Image();
                  BitmapImage src = new BitmapImage();
                  src.BeginInit();
                  src.UriSource = new Uri(pathToImage, UriKind.Absolute);
                  src.EndInit();
                  double ratio = src.Width / src.Height;
                  image.Source = src;
                  image.Stretch = Stretch.Uniform;
                  image.Height = canvas1.Height;
                  image.Width = canvas1.Height * ratio;
                  canvas1.Children.Add(image);
                  Canvas.SetTop(image, 0);
                  Canvas.SetLeft(image, -999);
                  textBlocks.AddLast(image);
              }
              catch (Exception ex)
              {
                  HasError = true;
                  ErrorMessage = ex.Message;
              }
          }
  
          void AddTextBlock(string Text, SolidColorBrush color)
          {
              try
              {
                  double w = MeasureTextSize(Text, fontFamily, fontStyle, fontWeight, fontStretch, fontSize).Width;
  
                  TextBlock tb = new TextBlock();
                  tb.Text = Text;
                  tb.FontSize = 28;
                  tb.FontWeight = FontWeights.Normal;
                  tb.Foreground = color;
                  // tb.Background = Brushes.Blue;
                  tb.FontSize = fontSize = canvas1.Height / koeff;
                  tb.Width = w;
  
                  canvas1.Children.Add(tb);
  
                  Canvas.SetTop(tb, 0);
                  Canvas.SetLeft(tb, -9999);
  
                  textBlocks.AddLast(tb);
              }
              catch (Exception ex)
              {
                  HasError = true;
                  ErrorMessage = ex.Message;
              }
          }
  </code></pre>