[英]WPF Cut Corner Element
我正在嘗試創建類似於下圖 WPF 中的內容。此控件旨在成為我應用程序中所有內容的基本視圖,並將位於具有背景(可能是某種漸變)的 Window 控件內。
要求如下:
我已經為此奮斗了幾個小時,但作為 WPF 的新手,我開始發現自己在原地打轉。 我認為 WPF 的靈活性有很大的好處,但對於剛起步的人來說,這幾乎是令人生畏的。
任何幫助將非常感激! 謝謝!
試試這個開始吧:
<Grid Width="100" Height="100">
<Border Background="Green" CornerRadius="8,0,8,8">
<Border.Clip>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="0,0">
<PathFigure.Segments>
<LineSegment Point="90,0"/>
<LineSegment Point="100,10"/>
<LineSegment Point="100,100"/>
<LineSegment Point="0,100"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Border.Clip>
</Border>
</Grid>
我不知道如何'填充'剪輯,所以我用代碼制作了剪輯。 如果您需要更多幫助來添加更多屬性來控制顏色等,請告訴我。
碼:
public class Tabby : HeaderedContentControl
{
static Tabby()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Tabby), new FrameworkPropertyMetadata(typeof(Tabby)));
}
public double DogEar
{
get { return (double)GetValue(DogEarProperty); }
set { SetValue(DogEarProperty, value); }
}
public static readonly DependencyProperty DogEarProperty =
DependencyProperty.Register("DogEar",
typeof(double),
typeof(Tabby),
new UIPropertyMetadata(8.0, DogEarPropertyChanged));
private static void DogEarPropertyChanged(
DependencyObject obj,
DependencyPropertyChangedEventArgs e)
{
((Tabby)obj).InvalidateVisual();
}
public Tabby()
{
this.SizeChanged += new SizeChangedEventHandler(Tabby_SizeChanged);
}
void Tabby_SizeChanged(object sender, SizeChangedEventArgs e)
{
var clip = new PathGeometry();
clip.Figures = new PathFigureCollection();
clip.Figures.Add(
new PathFigure(
new Point(0, 0),
new[] {
new LineSegment(new Point(this.ActualWidth - DogEar, 0), true),
new LineSegment(new Point(this.ActualWidth, DogEar), true),
new LineSegment(new Point(this.ActualWidth, this.ActualHeight), true),
new LineSegment(new Point(0, this.ActualHeight), true) },
true)
);
this.Clip = clip;
}
}
Generic.xaml
<Style TargetType="{x:Type local:Tabby}">
<Setter Property="Padding"
Value="5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Tabby}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Border CornerRadius="3,0,0,0"
BorderBrush="Black"
BorderThickness="1"
Background="Black">
<ContentPresenter Content="{TemplateBinding Header}"
Margin="{TemplateBinding Padding}" />
</Border>
<Border CornerRadius="0,0,3,3"
BorderBrush="Black"
BorderThickness="1"
Background="White"
Grid.Row="1">
<ContentPresenter Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
使用它:
<my:Tabby DogEar="12"
x:Name="tabby1">
<my:Tabby.Header>
<TextBlock Foreground="White">Header</TextBlock>
</my:Tabby.Header>
<my:Tabby.Content>
<TextBlock Text="Content can be anything" />
</my:Tabby.Content>
</my:Tabby>
這是我使用自定義控件放在一起的一些代碼。
控制代碼:
using System;
using System.Windows;
using System.Windows.Controls;
namespace Test
{
public class ContentCard : HeaderedContentControl
{
static ContentCard()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ContentCard), new FrameworkPropertyMetadata(typeof(ContentCard)));
}
}
}
控制xaml(在Themes / Generic.xaml文件夾中)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:test="clr-namespace:Test">
<Style TargetType="{x:Type test:ContentCard}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type test:ContentCard}">
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="0" Background="{TemplateBinding Background}" CornerRadius="10,0,0,0" Height="30">
<ContentControl Content="{TemplateBinding Header}" VerticalAlignment="Center" Margin="10,0,0,0" />
</Border>
<Path Grid.Row="0" Grid.Column="1" Fill="{TemplateBinding Background}" Data="M0,0 L20,15 L20,30 L0,30 L0,0Z"/>
<Border Grid.Row="1" Grid.ColumnSpan="2" BorderBrush="{TemplateBinding Background}" BorderThickness="1,0,1,1" CornerRadius="0,0,10,10" Padding="5" Background="White">
<ContentControl Content="{TemplateBinding Content}" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
這是你如何使用它:
<test:ContentCard Grid.RowSpan="4" Grid.ColumnSpan="2" Margin="200" Background="Black">
<test:ContentCard.Header>
<TextBlock Text="Title" Foreground="White" />
</test:ContentCard.Header>
<test:ContentCard.Content>
<TextBlock Text="This is some content" Foreground="Black" />
</test:ContentCard.Content>
</test:ContentCard>
謝謝你的帖子,這真是太棒了! 我已經修改以制作我自己的切角邊框 class 和下面相同的用法
public class CornerCutBorder : Border
{
public CornerRadius CornerCutSize
{
get { return (CornerRadius)GetValue(CornerCutSizeProperty); }
set { SetValue(CornerCutSizeProperty, value); }
}
public static readonly DependencyProperty CornerCutSizeProperty = DependencyProperty.Register("CornerCutSize", typeof(CornerRadius),typeof(CornerCutBorder),new UIPropertyMetadata(new CornerRadius(), DogEarPropertyChanged));
private static void DogEarPropertyChanged(DependencyObject obj,DependencyPropertyChangedEventArgs e)
{
((CornerCutBorder)obj).Resized();
}
public CornerCutBorder()
{
this.SizeChanged += new SizeChangedEventHandler(Border_SizeChanged);
}
void Border_SizeChanged(object sender, SizeChangedEventArgs e)
{
Resized();
}
void Resized()
{
var clip = new PathGeometry();
clip.Figures = new PathFigureCollection();
RectangleGeometry rectangleGeometry = new RectangleGeometry(new Rect()
{
Width = this.ActualWidth,
Height = this.ActualHeight
});
clip.AddGeometry(rectangleGeometry);
if (CornerCutSize.TopLeft > 0)
{
clip.Figures.Add(
new PathFigure(
new Point(0, 0),
new[] {
new LineSegment(new Point(CornerCutSize.TopLeft, 0), true),
new LineSegment(new Point(0, CornerCutSize.TopLeft), true) },
true)
);
}
if (CornerCutSize.TopRight > 0)
{
clip.Figures.Add(
new PathFigure(
new Point(this.ActualWidth - CornerCutSize.TopRight, 0),
new[] {
new LineSegment(new Point(this.ActualWidth, 0), true),
new LineSegment(new Point(this.ActualWidth, CornerCutSize.TopRight), true) },
true)
);
}
if (CornerCutSize.BottomLeft > 0)
{
clip.Figures.Add(
new PathFigure(
new Point(0, this.ActualHeight - CornerCutSize.BottomLeft),
new[] {
new LineSegment(new Point(0, this.ActualHeight), true),
new LineSegment(new Point(CornerCutSize.BottomLeft, this.ActualHeight), true) },
true)
);
}
if (CornerCutSize.BottomRight > 0)
{
clip.Figures.Add(
new PathFigure(
new Point(this.ActualWidth - CornerCutSize.BottomRight, this.ActualHeight),
new[] {
new LineSegment(new Point(this.ActualWidth, this.ActualHeight), true),
new LineSegment(new Point(this.ActualWidth, this.ActualHeight-CornerCutSize.BottomRight), true) },
true)
);
}
this.Clip = clip;
}
}
<local:CornerCutBorder CornerCutSize="30,100,100,50" Width="600" Height="400" BorderThickness="2" Background="Red" ></local:CornerCutBorder>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.