Search code examples
c#uwpwin2d

win2D CanvasControl DrawImage() throughs the error "Value Does Not Fall Within the expected Range"?


What i have Tried ? XAML Code:

 <Canvas x:Name="grid">
<canvas:CanvasControl Draw="CanvasControl_Draw" CreateResources="CanvasControl_CreateResourcesAsync" ></canvas:CanvasControl>
    </Canvas>

C# Code:

CanvasBitmap canvasBitmap;
private async void CanvasControl_CreateResourcesAsync(CanvasControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{
  canvasBitmap = await CanvasBitmap.LoadAsync(sender, @"Assets\Square150x150Logo.scale-200.png");
  sender.Invalidate();
}
private void  CanvasControl_Draw(CanvasControl sender, CanvasDrawEventArgs args)
{
   Vector2 Vector = new Vector2();
   Vector.X = 10;
   Vector.Y = 10;
   args.DrawingSession.DrawImage(canvasBitmap,Vector);          
}

While using Canvas,the CanvasControl won't fire the Draw Event and if i use Grid instead of Canvas ,it fire the Draw event of CanvasControl. I need Canvas in the Background .And the Error "The Value does Not Fall Within The Expected Range " also occurs.Can Any one help me??


Solution

  • While using Canvas,the CanvasControl won't fire the Draw Event

    Canvas is a control that uses absolute positioning. CanvasControl will not render without explicitly setting the Width or Height, and naturally will not trigger the Draw event.

    If you want to trigger the Draw event, please set the Width and Height properties of CanvasControl, such as:

    <Canvas x:Name="grid">
        <canvas:CanvasControl Draw="CanvasControl_Draw" 
                              CreateResources="CanvasControl_CreateResources"
                              Width="500" Height="500"
                              />
    </Canvas>
    

    The Error "The Value does Not Fall Within The Expected Range " also occurs.

    In simple terms, the reason for this error is that the Draw method is ready to render images that have not yet been loaded.

    If you want to handle asynchronous methods in the CreateResources event, such as image loading, you can consider doing this:

    CanvasBitmap canvasBitmap;
    private void CanvasControl_CreateResources(CanvasControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
    {
        args.TrackAsyncAction(CreateResourceAsync(sender).AsAsyncAction());
        sender.Invalidate();
    }
    
    private async Task CreateResourceAsync(CanvasControl sender)
    {
        canvasBitmap = await CanvasBitmap.LoadAsync(sender, @"Assets\Square150x150Logo.scale-200.png");
    }
    

    This ensures that the Draw event will not be triggered before the CreateResources event ends.

    Thanks.