我有一个GeometryModel3D
的{{1}}与DiffuseMaterial
使用ImageBrush
且数据绑定ImageSource
的WPF控件。
我的目标是在鼠标悬停时显示“横截面”,为此我可以在对象上获得正确的位置。问题是:WPF中没有“3D Line”。
我已经在ImageSource
的图像中绘制了一条线,并且视觉效果非常符合我的要求。
所以我计划执行以下操作:生成一次基本图像,然后在其上绘制相应的行,将属性设置为ImageSource
。
我考虑了两种方法:
拥有BitmapImage
类型的绑定ImageSource。然后我用空白纹理(没有线条)创建一次System.Drawing.Bitmap
,然后每次我想让线条改变位置时,我重新创建BitmapImage
用System.Drawing.Graphics
绘制一条线;
拥有DrawingGroup
类型的绑定ImageSource。然后我创建一次System.Windows.Media.ImageDrawing
,然后每次我希望该行改变位置时,我只通过更改由一行组成的DrawingGroup
来重新创建GeometryDrawing
。
一种方法与另一种方法有任何固有的优势吗?
答案 0 :(得分:1)
我必须承认,我从未真正测试过性能差异,但我知道Drawing
类能够以轻量级的方式操作基本的形状和图像。来自MSDN上的Drawing
Class页:
绘图对象是轻量级对象,可以将几何形状,图像,文本和媒体添加到应用程序中。绘图对象被认为是轻量级的,因为它们不支持布局,输入概述和焦点。由于它们的性能优势,图纸非常适合背景和剪贴画。在Visual Level编程时也可以使用绘图。
相反,BitmapImage
类内置了各种额外的功能和便利功能,使其重量轻于Drawing
类。来自MSDN上的Imaging Overview页:
BitmapImage是一种专门针对可扩展应用程序标记语言(XAML)加载而优化的BitmapSource,是一种将图像显示为图像控件源的简便方法。
答案 1 :(得分:0)
我最终更换了旧的基于GDI +的“Bitmap上的图形,然后转换为BitmapImage”
通过WPF / XAML非常友好的方式生成图像,使用一种有点笨重但实际上非常简单的方式来堆叠Drawing
个对象的“层”,消除了很多代码隐藏。
该行本身是一个硬编码的行,其Geometry.Transform.Y
属性由代码隐藏中的事件直接使用alturaFatia
名称设置。
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<ImageBrush>
<ImageBrush.ImageSource>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup.ClipGeometry>
<RectangleGeometry Rect="{Binding LimitesMapa}" />
</DrawingGroup.ClipGeometry>
<ImageDrawing x:Name="MapaAtivo"
ImageSource="{Binding MapaAtivo}" Rect="{Binding LimitesMapa}"/>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Thickness="2" Brush="Blue"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<LineGeometry>
<LineGeometry.StartPoint>
<Point X="-200" Y="0"/>
</LineGeometry.StartPoint>
<LineGeometry.EndPoint>
<Point X="200" Y="0" />
</LineGeometry.EndPoint>
<LineGeometry.Transform>
<TranslateTransform x:Name="alturaFatia" Y="-200" />
</LineGeometry.Transform>
</LineGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</ImageBrush.ImageSource>
</ImageBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>