In my C# .NET Framework 4.8 project I'm trying to derive the WindowsElement class to implement some additional functions in the new class. For example ClickInMiddleOfControl, IsVisible or SelectedItem (in a ComboBox).
public class WindowsElementWrapper : WindowsElement
{
public WindowsElementWrapper(RemoteWebDriver parent, string id) : base(parent, id) { }
public void ClickInMiddleOfControl()
{
var rect = this.Rect;
var offsetx = (int)(0.5 * rect.Width);
var offsety = (int)(0.5 * rect.Height);
new Actions(Helper.Session)
.MoveToElement(this, 0, 0)
.MoveByOffset(offsetx, offsety)
.Click()
.Build()
.Perform();
}
}
I then try to cast a WindowsElement to my WindowsElementWrapper.
var element = (WindowsElementWrapper)Session.FindElementByName("ElementName");
element.ClickInMiddleOfControl();
But on runtime I get the following error message:
System.InvalidCastException: 'Unable to cast object of type OpenQA.Selenium.Appium.Windows.WindowsElement' to type 'WEW.WindowsElementWrapper'.'
Is it not possible to derive from the WindowsElement class? Or am I making a fundamental mistake?
A cast from WindowsElement
to WindowsElementWrapper
is a downcast.
In order for a downcast to succeed, the runtime-type of the object has to be of the target-type itself, or a type derived from it.
Although a WindowsElementWrapper
is a WindowsElement
, a WindowsElement
does not have to be a WindowsElementWrapper
.
In other words, this downcast can never succeed, unless the SeleniumAPI instantiates the object as a WindowsElementWrapper
to begin with.
In order to achieve what you want to do, you may apply one of these designs:
Composition
public class WindowsElementWrapper
{
private readonly WindowsElement element;
public WindowsElementWrapper(WindowsElement element, (int Width, int Height) rect)
{
this.element = element;
Rect = rect;
}
public (int Width, int Height) Rect { get; init; }
public void ClickInMiddleOfControl()
=> new Actions(Helper.Session)
.MoveToElement(element, 0, 0)
.MoveByOffset(Rect.Width / 2, Rect.Height / 2)
.Click()
.Build()
.Perform();
}
Extension methods
public static class Extensions
{
public static void ClickInMiddleOfControl(this WindowsElement source, (int Width, int Height) rect)
=> new Actions(Helper.Session)
.MoveToElement(source, 0, 0)
.MoveByOffset(rect.Width / 2, rect.Height / 2)
.Click()
.Build()
.Perform();
}
Best Regards