2011-02-13 39 views
2

我想将OpacityMask设置为一个控件,但我需要动态构建该遮罩。 这里是它应该如何看:使用VisualBrush作为OpacityMask

http://i54.tinypic.com/350lc3a.png
整个(红色)的宽度和高度的矩形是动态的,基于宽度和父控制的高度。但是我需要在左上角和右上角放置两个小矩形(静态宽度和高度),如图所示。那么我怎么能做到这一点?

我尝试这样的代码,但它不工作:(没有什么是显示在所有)

<Border BorderBrush="#80FFFFFF" BorderThickness="1" CornerRadius="5"> 
    <Border.OpacityMask> 
     <VisualBrush> 
      <VisualBrush.Visual> 
       <DockPanel> 
        <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Height="2"> 
         <Border Background="Transparent" Width="12" VerticalAlignment="Stretch" HorizontalAlignment="Left" /> 
         <Border Background="Black" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" /> 
         <Border Background="Transparent" Width="12" VerticalAlignment="Stretch" HorizontalAlignment="Right" /> 
        </StackPanel> 

        <Border Background="Black" /> 
       </DockPanel> 
      </VisualBrush.Visual> 
     </VisualBrush> 
    </Border.OpacityMask> 
</Border> 

它甚至有效使用VisualBrush这种方式(作为OpacityMask)?

回答

3

如果我正确理解您的问题,您希望图像中的黑色方块透明吗?

更新:上传样本这里的项目:http://www.mediafire.com/?5tfkd1cxwfq0rct

我认为问题是,VisualBrushPanel不会延长。您可以通过绑定的宽度和高度得到想要的效果无论Panel您使用的Border

<Border Name="border" BorderBrush="Red" BorderThickness="1" CornerRadius="5"> 
    <Border.OpacityMask> 
     <VisualBrush> 
      <VisualBrush.Visual> 
       <Grid Width="{Binding ElementName=border, Path=ActualWidth}" 
         Height="{Binding ElementName=border, Path=ActualHeight}"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="20"/> 
         <ColumnDefinition Width="*"/> 
         <ColumnDefinition Width="20"/> 
        </Grid.ColumnDefinitions> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="20"/> 
         <RowDefinition Height="*"/> 
        </Grid.RowDefinitions> 
        <Rectangle Fill="Transparent" Grid.Column="0"/> 
        <Rectangle Fill="Black" Grid.Column="1"/> 
        <Rectangle Fill="Transparent" Grid.Column="2"/> 
        <Rectangle Fill="Black" Grid.Row="1" Grid.ColumnSpan="3"/> 
       </Grid> 
      </VisualBrush.Visual> 
     </VisualBrush> 
    </Border.OpacityMask> 
    <Grid> 
     <TextBlock Text="Testing OpacityMask with a rather long string................." Grid.ZIndex="3"/> 
     <Rectangle Fill="Green"/> 
    </Grid> 
</Border> 

更新的ActualWidth的和的ActualHeight再次
的DropShadowEffect的装饰儿童Border似乎推的OpacityMask都是Verticaly和Horizo​​ntaly。更糟糕的是它似乎堆叠起来,所以在你的例子中,当你有三个DropShadowEffects三个嵌套的Decorators时,BlurRadius的总和是45(20 + 15 + 10),所以不透明度蒙版被推送45(至少它看起来像是在发生什么事情,但有点难以分辨......)。您可以尝试通过增加ColumnDefinition Widths和RowDefinition Heights来弥补这一点,但我认为很难找到动态解决方案。

对您的问题更好的方法可能是使用Border.Clip,但这并不容易。

Point1: 0, 2 
Point2: 12, 2 
Point3: 12, 0 
Point4: Width of Border - 12, 0 
Point5: Width of Border - 12, 2 
Point5: Width of Border, 2 
Point6: Width of Border, Height of Border 
Point7: 0, Height of Border 

更新3
想出了一个更好的解决方案,不需要那么多的绑定。创建一个派生自Border的自定义类并重写GetLayoutClip。这适用于Designer和Runtime。为了提高灵活性ClippedBorder你能介绍一些依赖属性,而不是使用硬编码的2和12新样本这里应用:http://www.mediafire.com/?9i13rrqpbmzdbvs

public class ClippedBorder : Border 
{ 
    protected override Geometry GetLayoutClip(Size layoutSlotSize) 
    { 
     PathGeometry pathGeometry = new PathGeometry(); 
     pathGeometry.Figures = new PathFigureCollection(); 

     //Point1: 0, 2 
     PathFigure pathFigure = new PathFigure(); 
     pathFigure.StartPoint = new Point(0, 2); 

     //Point2: 12, 2 
     LineSegment lineSegment1 = new LineSegment(); 
     lineSegment1.Point = new Point(12, 2); 

     //Point3: 12, 0 
     LineSegment lineSegment2 = new LineSegment(); 
     lineSegment2.Point = new Point(12, 0); 

     //Point4: Width of Border - 12, 0 
     LineSegment lineSegment3 = new LineSegment(); 
     lineSegment3.Point = new Point(this.ActualWidth-12, 0); 

     //Point5: Width of Border - 12, 2 
     LineSegment lineSegment4 = new LineSegment(); 
     lineSegment4.Point = new Point(this.ActualWidth-12, 2); 

     //Point5: Width of Border, 2 
     LineSegment lineSegment5 = new LineSegment(); 
     lineSegment5.Point = new Point(this.ActualWidth, 2); 

     //Point6: Width of Border, Height of Border 
     LineSegment lineSegment6 = new LineSegment(); 
     lineSegment6.Point = new Point(this.ActualWidth, this.ActualHeight); 

     //Point7: 0, Height of Border 
     LineSegment lineSegment7 = new LineSegment(); 
     lineSegment7.Point = new Point(0, this.ActualHeight); 

     pathFigure.Segments.Add(lineSegment1); 
     pathFigure.Segments.Add(lineSegment2); 
     pathFigure.Segments.Add(lineSegment3); 
     pathFigure.Segments.Add(lineSegment4); 
     pathFigure.Segments.Add(lineSegment5); 
     pathFigure.Segments.Add(lineSegment6); 
     pathFigure.Segments.Add(lineSegment7); 

     pathGeometry.Figures.Add(pathFigure); 

     return pathGeometry; 
    } 
} 
+0

是黑色方块都应该是透明的。我试过你的代码,它不起作用 - 它显示了一切。我试图增加行/列上的宽度/高度,它仍然显示内容。 – Paya 2011-02-13 02:48:21