WPF custom animation thread

Daniel Santos 20 Reputation points
2023-09-16T17:21:29.6333333+00:00

Hello,

I have a small simple WPF application (I am learing by doing).

I made some custom drawing on a Canvas declared in XAML, by using code in the corresponding C# file.

Now I want to access the canvas from another thread to be able to apply geometric transformations to it and its contents.

But because the main thread owns the Canvas object, I cannot assign transformations to it.

Is there a specific way of being able to change the Canvas from other threads ?

Thanks,

Regards

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,802 questions
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,762 questions
Windows 11
Windows 11
A Microsoft operating system designed for productivity, creativity, and ease of use.
9,465 questions
{count} votes

Accepted answer
  1. Hui Liu-MSFT 48,491 Reputation points Microsoft Vendor
    2023-09-18T02:10:47.7033333+00:00

    Hi,@Daniel Santos . Welcome Microsoft Q&A. To access the canvas from another thread to be able to apply geometric transformations to it and its contents, you can try referring to the following code. If you still face the problem, please share with me the complete code that can reproduce your problem to analyze.

    xaml:

      <StackPanel>
           
            <Canvas Name="canvas" Height="200">
                <!--<Path x:Name="path" Stroke="Black" StrokeThickness="1" Data="19 39 ,20 60,"  Fill="Black" />-->
                <Polygon Points="15.3 19 10.2 8 0, 19 0.2, 18 10.3 1" Fill="Navy"></Polygon>
    
            </Canvas>
            <Button x:Name="btn" Content="thread" Click="btn_Click"/>
        </StackPanel>
    

    codebedhind:

    
     public partial class MainWindow : Window
        { 
            private Dispatcher uiDispatcher = Dispatcher.CurrentDispatcher;
    
            public MainWindow()
            {
                InitializeComponent();
            }
            void ApplyTransformationFromAnotherThread()
            {
                ScaleTransform scaleTransform = new ScaleTransform(2.0, 2.0);
    
               
                uiDispatcher.Invoke(() =>
                {
                   
                    Canvas myCanvas = canvas; 
    
                   
                    myCanvas.RenderTransform = scaleTransform;
                });
            }
    
            private void btn_Click(object sender, RoutedEventArgs e)
            {
                ApplyTransformationFromAnotherThread();
            }
        }
    
    

    Update:

    
     private int originX = 50;
            private int originY = 50;
            private int incrementX = 20;
            private int incrementY = 20;
            private int countX = 7;
            private int countY = 7;
            private int currentAngle = 0;
            private int rotateIncrement = 10;
            private RotateTransform rotateTransform;
    
            public MainWindow()
            {
                InitializeComponent();
    
                // Create and configure your canvas on the UI thread
                Canvas canvas = drawboard;
                rotateTransform = new RotateTransform();
                rotateTransform.CenterX = originX + 4 * incrementX;
                rotateTransform.CenterY = originY + 4 * incrementY;
                canvas.RenderTransform = rotateTransform;
    
                for (int xindex = 0; xindex < countX; xindex++)
                {
                    for (int yindex = 0; yindex < countY; yindex++)
                    {
                        Control cross11 = new Control();
                        cross11.Template = (ControlTemplate)canvas.FindResource("crosshairs");
                        Canvas.SetTop(cross11, originY + yindex * incrementY);
                        Canvas.SetLeft(cross11, originX + xindex * incrementX);
                        canvas.Children.Add(cross11);
                        cross11.Name = "cross_" + xindex + "_" + yindex;
                    }
                }
    
                // Start a DispatcherTimer to update the rotation
                DispatcherTimer timer = new DispatcherTimer();
                timer.Interval = TimeSpan.FromMilliseconds(100); // Adjust the update interval as needed
                timer.Tick += Timer_Tick;
                timer.Start();
            }
    
            private void Timer_Tick(object sender, EventArgs e)
            {
                // Update the rotation angle on each tick
                currentAngle += rotateIncrement;
                rotateTransform.Angle = currentAngle;
            }
    

    The result:

    enter image description here


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.