我在UWP项目中有一个类,该类派生自Windows.UI.Xaml.Shapes.Shape:
public class Hex : Windows.UI.Xaml.Shapes.Shape
{
public Hex()
{
}
}
当我尝试在mainPage.cs中实例化此类的新成员时,我收到一个InvalidCastException,如下所示:
System.InvalidCastException: Specified cast is not valid.
at Windows.UI.Xaml.Shapes.Shape..ctor()
at App1.Hex..ctor()
at App1.MainPage.Button_Click(Object sender, RoutedEventArgs e)
这是mainPage.cs中的代码
private void Button_Click(object sender, RoutedEventArgs e)
{
var h = new Hex();
h.Width = 20;
}
但也不起作用。据我了解,应该可以从派生类访问Shape的受保护构造函数,所以发生了什么?从Windows.UI.Xaml.Frameworkelemnt派生出来也可以做同样的事情。
答案 0 :(得分:1)
TLDR;没有严重的伤害是不可能的。但是...有可能。
我从重现问题开始,这是证明它的堆栈跟踪:
at Windows.UI.Xaml.Shapes.Shape..ctor()
at App1.Hex..ctor()
at App1.App1_XamlTypeInfo.XamlTypeInfoProvider.Activate_0_Hex()
at App1.App1_XamlTypeInfo.XamlUserType.ActivateInstance()
您会看到xaml元素(App1_XamlTypeInfo
)的类型提供程序是在运行时生成的,因此您无法使用自定义代码覆盖那些[Factory | Instance Creation | Builder]方法。
甚至没有尝试在Hex类中创建到Shape类型的隐式转换也可以解决该问题,这显然是C#的局限性,即您无法进行从子类到基类的自定义隐式转换,因为“已经编译的代码”或其他任何内容:(
另一种方法可能是优先考虑封装而不是继承,您将需要重新实现/暴露Shape类,并操纵其内部Shape实例,但是限制是您不能从WPF实现IShape和IShape2接口,因为它们被标记为内部。
据我所知,剩下的唯一选择就是修改WPF源代码,并分发该代码...我不知道与执行此类操作相关的许可问题。有关需要更改的类,请参见https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Shapes/Shape.cs,或者仅包含您自己的派生类型(例如Ellipse
),而https://referencesource.microsoft.com/#PresentationFramework/PresentationFramework.csproj仅指出构建起来很容易< em>需要引用。
希望有人来证明我错了...
答案 1 :(得分:1)
我也不明白。这很烦人,但显然您不能像预期的那样从Shape
派生(并且应该能够这样做。)相反,您必须从Path
继承并以这种方式添加路径。我将在此处针对SO链接另一个答案,该答案比重复说明的要好得多。
答案 2 :(得分:1)
当我尝试在mainPage.cs中实例化此类的新成员时 我收到一个InvalidCastException,如下所示:
this.state = { dob: moment(props.dob) }; <DatePicker date={this.state.dob} onDateChange={this.onDateChange} ... other attributes /> <input type="text" value={this.state.dob} onChange={this.onInputDateChange} ... other attributes /> onDateChange = (dob) => { if (dob) { this.setState(() => ({ dob })); } }; onInputDateChange = (e) => { const dob = e.target.value; if (dob) { this.setState(() => ({ dob })); } };
感谢您的反馈。我们完全理解,这种例外情况可能会引起混乱。
事实是,即使未密封Shape,也无法创建以这种方式创建的自定义形状。
要绘制自定义形状,请使用现有的Shape类型。
例如,可以使用具有6个顶点的多边形来轻松创建十六进制形状:
System.InvalidCastException: Specified cast is not valid.
at Windows.UI.Xaml.Shapes.Shape..ctor()
at App1.Hex..ctor()
at App1.MainPage.Button_Click(Object sender, RoutedEventArgs e)
对于更复杂的形状,客户可以改用Path类,如下所述: https://docs.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/shapes#path
如果需要,您可以在自定义控件中包装任何形状,例如使用UserControl: https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.usercontrol