【发布时间】:2010-11-21 00:48:22
【问题描述】:
假设我需要在 WPF 控件上设置不透明蒙版,以在精确位置突出显示它的一部分(假设在 (50;50) 位置有一个 50x50 的正方形)。为此,我创建了一个包含 2 个 GeometryDrawing 对象的 DrawingGroup:1 个半透明矩形用于控件的整个实际大小,1 个不透明矩形用于突出显示区域。然后我从这个 DrawingGroup 创建一个 DrawingBrush,将它的 Stretch 属性设置为 None 并将这个画笔设置为需要遮罩的控件的 OpacityMask。
所有这些都可以正常工作,而没有任何东西“坚持”超出所述控制范围。但是,如果控件在其边界之外绘制某些内容,则外部点将成为应用不透明蒙版的起点(如果画笔与该侧对齐),并且整个蒙版移动该距离,从而导致意外行为。
我似乎无法找到一种方法来强制从控件的边界应用蒙版,或者至少获得控件的实际边界(包括粘贴部分),以便我可以相应地调整我的蒙版。
任何想法都非常感谢!
更新:这是一个简单的测试用例 XAML 和演示问题的屏幕截图:
我们有 2 个嵌套的 Borders 和 Canvas 在最后一个与上面提到的正方形:
<Border Padding="20" Background="DarkGray" Width="240" Height="240">
<Border Background="LightBlue">
<Canvas>
<Rectangle Canvas.Left="50" Canvas.Top="50" Width="50" Height="50"
Stroke="Red" StrokeThickness="2"
Fill="White"
/>
</Canvas>
</Border>
</Border>
它的外观如下:
(来源:ailon.org)
现在我们在第二个边框上添加一个 OpacityMask,这样除了我们的正方形之外,它的每个部分都是半透明的:
<Border.OpacityMask>
<DrawingBrush Stretch="None" AlignmentX="Left" AlignmentY="Top">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="#30000000">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,200,200" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="50,50,50,50" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Border.OpacityMask>
一切看起来都如预期:
(来源:ailon.org)
现在我们在画布上添加一条线,在边框左侧伸出 10 个像素:
<Line X1="-10" Y1="150" X2="120" Y2="150"
Stroke="Red" StrokeThickness="2"
/>
蒙版向左移动 10 个像素:
(来源:ailon.org)
Update2:作为一种解决方法,我在边界之外添加了一个大得可笑的透明矩形并相应地调整我的蒙版,但这是一个非常讨厌的解决方法。
Update3:注意:带有矩形和线条的画布只是作为某些对象超出其边界的示例。在此示例的上下文中,它应该被视为某种黑匣子。您无法更改它的属性来解决一般问题。这与只是移动线条使其不会突出一样。
【问题讨论】:
-
查看您的代码会很有帮助。
-
添加示例代码和截图
-
+1 用于添加详细的复制案例。
-
你的问题发生是因为边框由于绘制的线而向左移动(你已经知道:)).. 那么你尝试将矩形绑定到边框或它的不透明蒙版怎么样? (真的不知道是否可能)..如果是的话..我相信它会解决你的问题。
-
我的例子只是为了表明 OpacityMask 应用于控件的整个边界(包括任何超出边界的部分)。而且我找不到改变这种行为的方法,或者至少找不到获得那些“实际”界限的方法。这不是一个需要解决的现实生活中的例子。我可以解决这个特定的任务。但我需要一个通用的解决方案,因为每次找到解决方法时,我都会在一段时间后再次碰壁。
标签: wpf layout opacity mask viewport