要知道,就像太空堡垒纸一样!我已经给出了一些建议,但现在我很困惑。我还没有走几何路线,所以我会尽力解释。

我希望边框要大一些,但要像CornerRadius一样包含固定大小的角。除了圆角,我希望它们是锥形的,例如:

/---------\
|         |
|         |
\_________/


我已经做了两次尝试:


我的第一次尝试是尝试操纵边界类。这只是行不通,因为拉伸形状会破坏几何形状和比例。
第二次尝试是开箱即用的。从字面上看。我创建了一个3x3的网格,并用4个边框填充,每个边框的厚度分别为2,0,0,0-0,2,0,0-0,0,2,0和0,0,0,2。最后一步是用Line连接边界。这是我的问题所在。


第一次尝试

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Grid>
      <Grid.Resources>
         <Style x:Key="MyPoly" TargetType="Polygon">
            <Setter Property="Points">
               <Setter.Value>
                  <PointCollection>
                     <Point X="0.10" Y="0.01"/>
                     <Point X="0.50" Y="0.01"/>
                     <Point X="0.60" Y="0.10"/>
                     <Point X="0.60" Y="0.50"/>
                     <Point X="0.50" Y="0.60"/>
                     <Point X="0.10" Y="0.60"/>
                     <Point X="0.01" Y="0.50"/>
                     <Point X="0.01" Y="0.10"/>
                  </PointCollection>
               </Setter.Value>
            </Setter>
         </Style>
      </Grid.Resources>
      <Border
         Width="100"
         Height="100"
         BorderBrush="Black"
         BorderThickness="3"
         CornerRadius="5"/>
      <Grid Width="400"
            Height="300">
         <Polygon
            Stroke="Purple"
            StrokeThickness="2"
            Style="{StaticResource MyPoly}" Stretch="Fill">
            <Polygon.Fill>
               <SolidColorBrush Color="Blue" Opacity="0.4"/>
            </Polygon.Fill>
            <Polygon.LayoutTransform>
               <ScaleTransform ScaleX="1" ScaleY="1"/>
            </Polygon.LayoutTransform>
         </Polygon>
      </Grid>
   </Grid>
</Page>


第二次尝试

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" SnapsToDevicePixels="True">
    <Grid>
        <Grid.Resources>
        </Grid.Resources>
        <Grid Width="200" Height="350" SnapsToDevicePixels="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="10"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="10"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="10"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="10"/>
            </Grid.RowDefinitions>
            <Border Grid.Column="0" Grid.Row="1" Margin="0" BorderBrush="Red" BorderThickness="2,0,0,0" Padding="0" SnapsToDevicePixels="True"/>
            <Border BorderThickness="1" BorderBrush="Black">
                <Line SnapsToDevicePixels="True" Stretch="Fill" Stroke="Red" StrokeThickness="2" X1="0" X2="1" Y1="1" Y2="0">
                </Line>
            </Border>
            <Border Grid.Column="1" Grid.Row="0" BorderBrush="Red" BorderThickness="0,2,0,0" SnapsToDevicePixels="True"/>
            <Border Grid.Column="2" Grid.Row="1" BorderBrush="Red" BorderThickness="0,0,2,0" SnapsToDevicePixels="True"/>
            <Border Grid.Column="1" Grid.Row="2" BorderBrush="Red" BorderThickness="0,0,0,2" SnapsToDevicePixels="True"/>
        </Grid>
    </Grid>
</Page>


线被设置为缩放到网格大小。将线属性设置为X1="0" X2="1" Y1="1" Y2="0"并使用Stretch="Fill"会将线扩展到边缘。但是,最终看起来像这样:

(令人讨厌的是,我无法发布图像,我需要去回答别人的问题才能获得代表。因此,相反,请转到此链接查看该行,或者将上面的XAML粘贴到Kaxaml中。)
http://img375.imageshack.us/img375/1996/border1.png

我在承载Line的Grid元素周围绘制了洋红色边框,以使问题更加明显。

如何扩展线条以真正填充间隙(例如,通过扩大网格内的可绘制区域),或者有更好的方法吗?

此外,变换会使线变形,使其更粗。我尝试扩大规模,但与此并不一致。生产线上的端盖看起来也很糟糕(例如三角形)。

最后,此方法仍然存在缺陷,因为我希望将来能够设置拐角大小,因此将行/列的边缘宽度设置为10似乎是一个绊脚石。绑定到属性可能会解决该问题,尽管我从未在Style中做到这一点。

感谢您的阅读,汤姆

最佳答案

WPF边框是从Decorator类继承的。编写自己的装饰器非常容易。在下方画一个边框,该边框围绕着一个“藏在”角落的孩子。

class FunkyBorder : Decorator
{
    public Brush BorderBrush
    {
        get { return (Brush)GetValue(BorderBrushProperty); }
        set { SetValue(BorderBrushProperty, value); }
    }

    public static readonly DependencyProperty BorderBrushProperty =
        DependencyProperty.Register("BorderBrush",
                                    typeof(Brush),
                                    typeof(FunkyBorder),
                                    new UIPropertyMetadata(Brushes.Transparent));

    protected override void OnRender(DrawingContext drawingContext)
    {
        // TODO, make pen thickness and corner width (currently 10) into dependency properties.
        // Also, handle case when border don't fit into given space without overlapping.

        if (_pen.Brush != BorderBrush)
        {
            _pen.Brush = BorderBrush;
        }

        drawingContext.DrawLine(_pen, new Point(0, 10), new Point(10, 0));
        drawingContext.DrawLine(_pen, new Point(10, 0), new Point(ActualWidth - 10, 0));
        drawingContext.DrawLine(_pen, new Point(ActualWidth - 10, 0), new Point(ActualWidth, 10));
        drawingContext.DrawLine(_pen, new Point(0, 10), new Point(0, ActualHeight - 10));
        drawingContext.DrawLine(_pen, new Point(ActualWidth, 10), new Point(ActualWidth, ActualHeight - 10));
        drawingContext.DrawLine(_pen, new Point(0, ActualHeight - 10), new Point(10, ActualHeight));
        drawingContext.DrawLine(_pen, new Point(10, ActualHeight), new Point(ActualWidth - 10, ActualHeight));
        drawingContext.DrawLine(_pen, new Point(ActualWidth - 10, ActualHeight), new Point(ActualWidth, ActualHeight - 10));
    }

    private Pen _pen = new Pen(Brushes.Transparent, 2);
}


像这样使用:

   <BorderTest:FunkyBorder BorderBrush="Red">
        <TextBlock Text="Hello" />
    </BorderTest:FunkyBorder>

10-04 15:45
查看更多