3

在某些 xaml 中,我希望有一个从每个角仅向外几个像素的边框。因此,沿着顶部,边界将是,例如,左边缘的 5 个黑色像素,然后在顶部的其余部分是透明的,直到右边缘的 5 个像素,然后是边界的最后 5 个像素。右边缘将是黑色的。目的是为偶尔透明的事物的选择提供一些指导;但是,在此应用程序中,完整边框的存在会干扰内容(在感知视觉意义上)。角不是圆的。

看起来像这样的东西:

--          --
|            |




|            |
--          --

我应该使用什么类型的刷子来达到这种效果?

我尝试过线性渐变,如下所示:

<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
    <GradientStop Color="Black" Offset="0" />
    <GradientStop Color="Black" Offset="0.01" />
    <GradientStop Color="Transparent" Offset="0.0101" />
    <GradientStop Color="Transparent" Offset="0.9899" />
    <GradientStop Color="Black" Offset="0.99" />
    <GradientStop Color="Black" Offset="1" />
</LinearGradientBrush>

当然,这只适用于左上角和右下角。这对于预期的应用来说可能是合理的,但是只有当边界区域是正方形时,每个角上的线的大小才相同(例如,如果边界区域是一个长矩形,那么边界部分沿着一个更远一侧比另一侧)。

我确实注意到渐变画笔上“Absolute”的 MappingMode 值。这适用于左上角,但不适用于其他角落。

我还尝试了 RadialGradientBrush,认为我可以让一个环击中角落,但未能成功将其正确居中或使其沿两侧击中相等的长度。

这是 ListBox 中 ItemContainerStyle 的一部分,并且使用 IsSelected 的触发器更改边框。出于这个原因,我也不能在边界内(边界内等)做边界。

编辑#2:我还尝试了 VisualBrush。我知道我可以在网格中获得我想要的行为(至少是拉伸行为)。

<VisualBrush Stretch="Fill">
    <VisualBrush.Visual>
        <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="10" MaxWidth="10" MinWidth="10" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="10" MaxWidth="10" MinWidth="10" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="10" MaxHeight="10" MinHeight="10" />
                <RowDefinition Height="*" />
                <RowDefinition Height="10" MaxHeight="10" MinHeight="10" />
            </Grid.RowDefinitions>
            <Rectangle Grid.Column="0" Grid.Row="0" Fill="Black" />
            <Rectangle Grid.Column="1" Grid.Row="0" Fill="Transparent" />
            <Rectangle Grid.Column="2" Grid.Row="0" Fill="Black" />
            <Rectangle Grid.Column="0" Grid.Row="1" Fill="Transparent" />
            <Rectangle Grid.Column="1" Grid.Row="1" Fill="Transparent" />
            <Rectangle Grid.Column="2" Grid.Row="1" Fill="Transparent" />
            <Rectangle Grid.Column="0" Grid.Row="2" Fill="Black" />
            <Rectangle Grid.Column="1" Grid.Row="2" Fill="Transparent" />
            <Rectangle Grid.Column="2" Grid.Row="2" Fill="Black" />
        </Grid>
    </VisualBrush.Visual>
</VisualBrush>

但是,这也行不通。似乎在画笔内进行大小调整的方式不同。在这种情况下,VisualBrush 中 Grid 的大小最终为 20x20,中间透明部分不占空间。将 Horizo​​ntalAlignment 和 VerticalAlignment 设置为 Stretch 也无济于事。VisualBrush 上的 Stretch="Fill" 也没有做任何事情。

编辑#1:更广泛的背景:

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Style.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
        </Style.Resources>
        <Setter Property="Margin" Value="3" />
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="BorderThickness" Value="5" />
                <Setter Property="Padding" Value="0" />
                <Setter Property="BorderBrush" Value="Fuchsia" />
            </Trigger>
            <Trigger Property="IsSelected" Value="False">
                <Setter Property="BorderThickness" Value="1" />
                <Setter Property="Padding" Value="4" />
                <Setter Property="BorderBrush">
                    <Setter.Value>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                            <GradientStop Color="Black" Offset="0" />
                            <GradientStop Color="Black" Offset="0.01" />
                            <GradientStop Color="Transparent" Offset="0.0101" />
                            <GradientStop Color="Transparent" Offset="0.9899" />
                            <GradientStop Color="Black" Offset="0.99" />
                            <GradientStop Color="Black" Offset="1" />
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</ListBox.ItemContainerStyle>
4

3 回答 3

2

您可以使用Path... 这将绘制类似于您正在寻找的东西:

<Path Stroke="Black" Stretch="Fill" 
      Data="M0,0 l10,0 m80,0 l10,0 m0,0 l0,10 m0,80 l0,10 m0,0 l-10,0 m-80,0 l-10,0 m0,0 l0,-10 m0,-80 l0,-10"
      Height="100" Width="100" Margin="10" />

完整代码示例:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Path Stroke="Black" Stretch="Fill" 
              Data="M0,0 l10,0 m80,0 l10,0 m0,0 l0,10 m0,80 l0,10 m0,0 l-10,0 m-80,0 l-10,0 m0,0 l0,-10 m0,-80 l0,-10"
              Height="100" Width="100" Margin="10" />
    </Grid>
</Window>
于 2013-12-05T21:27:07.423 回答
1

径向渐变画笔可能会实现您正在寻找的东西。将径向画笔的中心设置为框的中心。从透明的中心颜色开始,从中心淡化到所需的“边框颜色”(黑色),然后将半径设置得足够大,使黑色只出现在角落。

并确保将“渐变”设置为非常短 - 不要逐渐淡化它,而是让它变得清晰。

如果你调整它的大小,你会得到类似于下图(很差)的效果。红框代表你的内容。该框外的所有内容都说明了您的角落会是什么样子。使“透明”部分的半径更大,以使您的黑角更小。

最后; 这几乎只会在细边框下看起来不错。如果你有一个粗边框,它会在角刷的“尖端”看起来“有趣”。

在此处输入图像描述

更新:

这是一个带有一些代码的实际示例:

<Border BorderThickness="1" Height="100" Width="100">
    <Border.BorderBrush>
        <RadialGradientBrush RadiusX="0.6" RadiusY="0.6">
            <GradientStop Color="Black" Offset="1"/>
            <GradientStop Color="#00000000" Offset="0.99"/>
        </RadialGradientBrush>
    </Border.BorderBrush>
    <Rectangle Fill="Red" />
</Border>

这就是它的样子:

在此处输入图像描述

对于矩形(即不是完美的正方形),为了保持角的大小相同,您必须相应地缩放 RadiusX 和 RadiusY 值。它们应该随着宽度/高度比缩放。

于 2014-01-03T18:29:01.530 回答
1

这是一个有趣的问题,所以这里还有另一种可能性。我希望您同意这可以作为与我之前的答案完全分开的答案...

您可以使用包含在网格中的一组简单形状的组合来实现您想要的效果。将您的“内容”框放在 4 个黑色矩形的顶部,每个黑色矩形都位于网格的适当角落。

这是我蹩脚的油漆插图。再次,红色框表示您的内容。该红色框之外的任何内容都是用户将看到的边框。

在此处输入图像描述

以及带有代码的真实示例:

<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Width="300" Height="200">
    <!-- These rectangles will be the four corner "borders" -->
    <Rectangle Fill="Black" Width="50" Height="50" HorizontalAlignment="Left" VerticalAlignment="Top" />
    <Rectangle Fill="Black" Width="50" Height="50" HorizontalAlignment="Left" VerticalAlignment="Bottom" />
    <Rectangle Fill="Black" Width="50" Height="50" HorizontalAlignment="Right" VerticalAlignment="Top" />
    <Rectangle Fill="Black" Width="50" Height="50" HorizontalAlignment="Right" VerticalAlignment="Bottom" />

    <!-- Here is the content.  The "margin" property will effectively be the thickness of your corner borders. -->
    <Rectangle Fill="Red" Margin="2" />        
</Grid>

它看起来像这样:

在此处输入图像描述

这具有很好的扩展性的额外好处;无论您的内容大小如何,角边框的大小都将始终相同。此外,边框可以是您喜欢的任何厚度,而不会像以前的径向刷答案那样看起来“奇怪”。

于 2014-01-03T18:50:55.180 回答