使用的VisualBrush为OpacityMaskVisualBrush、OpacityMask

2023-09-03 04:18:59 作者:拥抱好吗让我踏实

我想设置 OpacityMask 来控制,但我需要动态地建立一个面具。 下面是它应该如何看:

I want to set OpacityMask to a control, but I need to build that mask dynamically. Here is how it should look:

整个(红色)矩形的宽度和高度是动态的,基于宽度和父控制的高度。但我需要把两个小矩形(静态的宽度和高度)的左上角和右上角,如图所示的图像。所以,我怎样才能做到这一点?

The width and height of the whole (red) rectangle is dynamic, based on width and height of parent control. But I need to place two small rectangles (static width and height) in top left and top right corner, as shown on image. So how can I make this happen?

我想这code,但它不工作:(没有显示在所有的)

I tried this code, but it doesn't work: (nothing is displayed at all)

<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 )?

推荐答案

如果我正确地理解你的问题,你想你像那些黑色的方块是透明的?

If I understand your question correctly you want those Black squares in you image to be transparent?

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

Update: Uploaded sample project here: http://www.mediafire.com/?5tfkd1cxwfq0rct

我觉得问题是,面板的VisualBrush 将不会延长。您可以通过绑定的宽度和任何面板您使用的ActualWidth的和边境的ActualHeight

I think the problem is that the Panel inside the VisualBrush won't stretch. You could get the desired effect by Binding the Width and Height of whatever Panel you use to the ActualWidth and ActualHeight of the 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>

再次更新 该DropShadowEffect为边框的装饰孩子似乎推OpacityMask为边框既Verticaly和Horizo​​ntaly。什么更糟糕的是,它似乎堆叠,所以在你的例子,当你有三个DropShadowEffects三个嵌套的装修的BlurRadius的总和为45(20 + 15 + 10)所以OpacityMask推由45值(至少它看起来这是怎么回事,但它是一个有点难以启齿。)。您可以尝试通过增加ColumnDefinition宽度和RowDefinition高地,以弥补这一点,但我认为这将是很难找到一个动态的解决方案。

Update Again The DropShadowEffect for the Decorator Child of the Border seems to push the OpacityMask for the Border both Verticaly and Horizontaly. And what's even worse is that it seems to stack, so in your example when you have three DropShadowEffects for three nested Decorators, the sum of the BlurRadius is 45 (20+15+10) so the OpacityMask is pushed by a value of 45 (at least it looks like this is whats going on, but it's a little hard to tell..). You could try to compensate for this by increasing the ColumnDefinition Widths and RowDefinition Heights but I think it'll be hard to find a dynamic solution.

一个更好的办法,您的问题可能是使用 Border.Clip 但这不来容易。

A better approach to your problem may be to use Border.Clip but that doesn't come easy either.

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 想出了一个更好的解决方案,不需要那么多的绑定。创建一个源自边框自定义类,并覆盖GetLayoutClip。这无论是在设计和运行工作。为了增加 ClippedBorder 的灵活性,你可以介绍一些依赖属性,而不使用硬$ C $ 2张CD和12新样本位置的应用程序:的 http://www.mediafire.com/?9i13rrqpbmzdbvs

Update 3 Came up with a better solution that doesn't require so many Bindings. Create a custom class that derives from Border and override GetLayoutClip. This works both in Designer and Runtime. To increase flexibility of ClippedBorder you could introduce some Dependency Properties to use instead of the hardcoded 2 and 12. New sample app here: 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;
    }
}
相关推荐