Unable to cast object of type 'Windows.UI.Xaml.Shapes.Polyline' to type 'Windows.UI.Xaml.IUIElement10'

Victor Chen 106 Reputation points
2020-06-22T09:50:19.007+00:00

Disclaimer: This problem occurred in Win10 1809, Win10 1909 test passed

I found a strange thing, I took a UIElement object (named polyline1) from Canvas.Children, The full name of this object is Windows.UI.Xaml.Shapes.Polyline, when I use (polyline1 as Polyline)?.ActualOffset When I get the error mentioned in the title: Unable to cast object of type'Windows.UI.Xaml.Shapes.Polyline' to type'Windows.UI.Xaml.IUIElement10', even if I use polyline1.ActualOffset I will get the same error.

Here is part of the code:

xml

<Canvas x:Name="canvas">
    <Polyline x:Name="polyline1" Points="0,0 140,0 140,60" />
    <Polyline x:Name="polyline2" Points="0,0 240,0 240,60" />
    ....
</Canvas>

code

try
{
    var polyline1 = canvas.Children.FirstOrDefault(x => x.GetType().Name == typeof(Polyline).Name);
    Debug.Write($"fullname: {polyline1.GetType().FullName}");
    Debug.Write($"is polyline: {polyline1 is Polyline}");
    Debug.Write($"as polyline: {polyline1 as Polyline}");
    Debug.Write($"as polyline.ActualOffset.X: {(polyline1 as Polyline)?.ActualOffset.X}")
}
catch(Exception ex)
{
    Debug.Write($"error: {ex}");
}

Output

fullname: Windows.UI.Xaml.Shapes.Polyline
is polyline: True
as polyline: Windows.UI.Xaml.Shapes.Polyline
error: System.InvalidCastException: Unable to cast object of type 'Windows.UI.Xaml.Shapes.Polyline' to type 'Windows.UI.Xaml.IUIElement10'.
   at System.StubHelpers.StubHelpers.GetCOMIPFromRCW_WinRT(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget)
   at Windows.UI.Xaml.UIElement.get_ActualOffset()
Universal Windows Platform (UWP)
{count} votes

Accepted answer
  1. Daniele 1,996 Reputation points
    2020-06-22T20:09:20.043+00:00

    As you can see in the documentation here https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.uielement.actualoffset, UIElement.ActualOffset was added with 10.0.18362.0 (1903). If you use TargetPlatformVersion is greater or equals to 10.0.18362.0, you are allowed to use in your code UIElement.ActualOffset and there are no compilation errors, but if your TargetPlatformMinVersion is smaller than 10.0.18362.0, than you have to add to your code extra checks before to use to use it.

    Use ApiInformation method to detect whether a specified member, type, or API contract is present, for example:

       try  
       {  
           UIElement polyline1 = canvas.Children.FirstOrDefault(x => x.GetType().Name == typeof(Polyline).Name);  
           Debug.Write($"fullname: {polyline1.GetType().FullName}");  
           Debug.Write($"is polyline: {polyline1 is Polyline}");  
           Debug.Write($"as polyline: {polyline1 as Polyline}");  
           bool isPropertyPresent = ApiInformation.IsPropertyPresent("Windows.UI.Xaml.UIElement", "ActualOffset");  
           double actualOffsetX = isPropertyPresent  
               ? polyline1.ActualOffset.X  
               : polyline1.TransformToVisual(canvas).TransformPoint(new Point(0, 0)).X;  
       }  
       catch (Exception ex)  
       {  
           Debug.Write($"error: {ex}");  
       }  
    

    The example above is just to show how you can use ApiInformation, in your particular case I think the best option is to use only

       polyline1.TransformToVisual(canvas).TransformPoint(new Point(0, 0)).X;  
    

0 additional answers

Sort by: Most helpful