Search code examples
c#.netavaloniaui

In AvaloniaUI, how to render without clearing


I am using a RenderTargetBitmap. I have a piece of code like this

using (var context = WorldImage.CreateDrawingContext()) {
    Pen pen = new Pen(Brushes.Black);
    context.DrawLine(pen, previousPoint, currentPoint);
}

The purpose of this code is to draw a curve by pairs of points. However, it doesn't work because it clears the image before each draw. How to disable this clearing?


Solution

  • How to disable this clearing?

    You can't. You must instead keep all the points that should be drawn, e.g. in a collection of Points.

    It is unclear what exactly you are trying to achieve. The following sample draws a polyline that follows the mouse cursor as long as the left mouse button is pressed.

    With an Image element in XAML

    <Grid>
        <Border BorderThickness="1" BorderBrush="Black"
                HorizontalAlignment="Center" VerticalAlignment="Center">
            <Image x:Name="image" Stretch="None"/>
        </Border>
    </Grid>
    

    the code below would draw the polyline. Note that in Avalonia there seems to be no automatic UI update when a RenderTargetBitmap is redrawn, hence the InvalidateVisual() on the Image element.

    private readonly RenderTargetBitmap bitmap = new(new PixelSize(400, 400));
    private readonly List<Point> polyline = [];
    
    public MainView()
    {
        InitializeComponent();
    
        image.Source = bitmap;
        image.PointerPressed += OnPointerPressed;
        image.PointerMoved += OnPointerMoved;
    }
    
    private void OnPointerPressed(object sender, PointerPressedEventArgs e)
    {
        polyline.Clear();
        polyline.Add(e.GetPosition(image));
    }
    
    private void OnPointerMoved(object sender, PointerEventArgs e)
    {
        var p = e.GetCurrentPoint(image);
    
        if (p.Properties.IsLeftButtonPressed)
        {
            polyline.Add(p.Position);
    
            using var context = bitmap.CreateDrawingContext();
    
            Pen pen = new(Brushes.Black);
    
            for (int i = 1; i < polyline.Count; i++)
            {
                context.DrawLine(pen, polyline[i - 1], polyline[i]);
            }
    
            image.InvalidateVisual();
        }
    }