Silverlight 中的自定义形状(从 WPF 移植应用程序)
我正在将 WPF 应用程序转换为 Silverlight。
该应用程序包含一个继承自 Shape 的类。它重写 DefiningGeometry 属性以返回 Path 对象。但是,Silverlight Shape 类没有 DefineingGeometry 属性。
在互联网上阅读我发现其他人也有同样的问题。解决方案似乎涉及直接从 Control 继承,并将 Content 属性设置为路径。但是,我还想保留我的事件处理程序(MouseEnter、MouseLeave、GotFocus、LostFocus),而且我希望它保持其位置并根据应用程序的其余部分按比例调整大小。
我主要是一名后端开发人员,所以这不是我的强项 - 如果有人能给我一个如何实现这一目标的概要示例,我将不胜感激。
I'm converting a WPF app to Silverlight.
The app includes a class which inherits from Shape. It overrides the DefiningGeometry property to return a Path object. However, the Silverlight Shape class doesn't have a DefiningGeometry property.
Reading on the internet I've found others with this same problem. The solution seems to involve inheriting from Control directly, and setting the Content property to the path. However, I also want to retain my event handlers (MouseEnter, MouseLeave, GotFocus, LostFocus) plus I would like it to keep it's position and resize proportionally to the rest of the application.
I'm mainly a back-end developer, so this isn't my forte - I'd appreciate it if anyone could give me an outline sample of how to achieve this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您将无法生成以相同方式工作的类,因为 Silverlight 不支持创建从
Shape
基类派生的自定义元素。无法在 Silveright 中创建自定义形状的原因是 Silverlight 不共享 WPF 的“可视层”。如果您想完全理解为什么您正在尝试的事情是不可能的,您需要了解 Silverlight 与 WPF 有何不同。 (如果您不在乎,请跳过接下来的 2 段。)
在 WPF 中,您可以在两个完全不同的级别上工作:可视层或框架层。视觉层的服务由WindowsBase.dll和PresentationCore.dll提供。这提供了基本的渲染和输入服务。但如果您想要样式、数据绑定、布局、模板等功能,则需要框架服务,而这些服务是由PresentationFramework.dll 提供的。形状类型 -
Rectangle
、Path
等 - 都是框架类型 - 它们派生自FrameworkElement
并且支持数据绑定、布局、动画等。但它们是在视觉层之上实现的 - 如果您查看 Reflector 或 ILDASM 中的任何Shape
类型,您会发现它们都覆盖了OnRender
方法,并且这就是定义实际形状的代码所在的位置。 (OnRender
是一个视觉层函数。)并且由于视觉层是完全受支持且有文档记录的 API,因此您可以在 WPF 中自由编写自己的形状 - 您可以编写完全相同类型的代码正如您将在内置形状类中找到的那样。Silverlight 并没有做出这种视觉/框架的区别 - 在 Silverlight 中,WPF 的视觉层本质上已经折叠到框架层中。因此,如果您查看 Reflector 或 ILDASM 中的形状类型,您会发现它们不包含
OnRender
方法,而且它们几乎是空的。这是因为在 Silverlight 中,形状都是内在的 - 该插件具有针对Ellipse
、Path
和所有其他形状的内置特殊处理。因此,这组形状不能在 Silverilight 中进行扩展。 Silverlight 中没有可重写的OnRender
方法。因此,您根本无法编写自己的从 Silverlight 中的Shape
派生的自定义类。因此,恐怕自定义
Control
或UserControl
将是最佳选择。但这不应阻止MouseEnter
和MouseLeave
工作。你真的发现这些不起作用吗?或者您只是假设它们不起作用?You will not be able to produce a class that works in the same way because Silverlight does not support the creation of custom elements that derive from the
Shape
base class.The reason it's impossible to create a custom shape in Silveright is that Silverlight does not share WPF's "visual layer". If you want to understand fully why what you're trying is impossible, you need to understand how Silverlight is very different from WPF here. (And if you don't care, skip the next 2 paragraphs.)
In WPF, you can work at two completely different levels: the visual layer, or the framework layer. The visual layer's services are provided by WindowsBase.dll and PresentationCore.dll. This provides basic rendering and input services. But if you want things like styling, data binding, layout, templating and so on, you need the framework services, and these are provided by PresentationFramework.dll. The shape types -
Rectangle
,Path
, and so on - are all framework types - they derive fromFrameworkElement
and they support data binding, layout, animation and so on. But they are implemented on top of the visual layer - if you look at any of theShape
types in Reflector or ILDASM you'll see they all override theOnRender
method, and that's where the code that defines the actual shape lives. (OnRender
is a visual layer function.) And because the visual layer is a fully supported and documented API, you're free to write your own shapes in WPF - you can write exactly the same sort of code as you'll find in the built-in shape classes.Silverlight doesn't make this visual/framework distinction - in Silverlight, WPF's visual layer has essentially collapsed into the framework layer. So if you look at the shape types in Reflector or ILDASM, you'll see that they contain no
OnRender
method, and they're almost empty. That's because in Silverlight, the shapes are all intrinsics - the plugin has built-in special handling forEllipse
,Path
, and all the other shapes. So the set of shapes is not open to extension in Silverilght. There is noOnRender
method to override in Silverlight. So you simply cannot write your own custom class that derives fromShape
in Silverlight.So, either a custom
Control
or aUserControl
will be the way to go, I'm afraid. This shouldn't stop theMouseEnter
andMouseLeave
from working though. Have you actually found that those don't work? Or are you just assuming that they won't work?如果保留现有的类(让我们将其称为 CustomShape),然后使用像 CustomShapeContainer 这样的东西从 Control 中继承,会怎么样? CustomShapeContainer 本质上只是 CustomShape 的包装器。然后,您可以将进入 CustomShapeContainer 的所有事件直接传递到 CustomShape,然后返回形状 DefininingGeometry 对象作为容器内容。
乍一看,这似乎是阻力最小的路径。
What if keep your existing class, lets call it CustomShape, as is, then inherent from Control with something like CustomShapeContainer? CustomShapeContainer would essentially just be a wrapper around CustomShape. You could then pass all of the events coming into CustomShapeContainer directly through into CustomShape and then return the shapes DefininingGeometry object as the Containers content.
At first glance, this seems like the path of least resistance.
您在 Silverlight 中没有相同的命名空间。 Silverlight xaml 是 WPF xaml 的子集,并且有些程序集未包含在 Silverright 中。这些技术适用于不同类型的操作系统解决方案。
你可能需要重新开始。但是,如果您使用 MVVM 模式,则只需很少的代码即可重用您的 ViewModel、模型和服务。也许资源、样式可以“按原样”重用。但观点:从新开始。
You do not have the same namespaces in Silverlight. Silverlight xaml is a subset of WPF xaml and there are assemblies which are not included in Silvelright. These technologies are intended for different kind os solutions.
You might need to start anew. However, if you used the MVVM pattern, very little code behind then you might be able to re-use your ViewModel, Model and services. Maybe resources, styles would be OK to reuse "as is". But the View: start new.
从 Silverlight 3 开始,有一种特殊类型的 Shape,称为 定义属性 Geometry类型的数据。您应该能够将创建 Geometry 的原始 WPF 代码移植到此 Data 属性。
Starting with Silverlight 3, there is a special type of Shape called Path that defines a property Data of Geometry type. You should be able to port the original WPF code that created a Geometry to this Data property.