I need to create a User Control in WPF with several shapes in a grid. The UserC ontrol should have beveled corners. I have no idea how to do that without drawing triangles at fixed positions.
Asked
Active
Viewed 108 times
0
-
5This question would be much better with a reference image as an example of what you are trying to recreate. – Gusdor Mar 14 '16 at 11:26
-
This should be the result: http://www.directupload.net/file/d/4293/jd6x6z2b_png.htm – Konstantin Mar 14 '16 at 12:43
-
[This similar question](http://stackoverflow.com/questions/561931/how-to-create-trapezoid-tabs-in-wpf-tab-control) should help. – icebat Mar 14 '16 at 13:29
1 Answers
0
In my opinion you should write your own Decorator. I wrote a simple code sample, which of course can be improved - maybe it should be. You can use my CutCornerBorder
class ad an hint:
public class CutCornerBorder : Decorator
{
private Pen cachedPen;
public static readonly DependencyProperty BorderThicknessProperty = DependencyProperty.Register("BorderThickness", typeof(double), typeof(CutCornerBorder), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(CutCornerBorder.OnClearPenCache)));
public static readonly DependencyProperty PaddingProperty = DependencyProperty.Register("Padding", typeof(Thickness), typeof(CutCornerBorder), new FrameworkPropertyMetadata(default(Thickness), FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), new ValidateValueCallback(CutCornerBorder.IsThicknessValid));
public static readonly DependencyProperty CornerCutProperty = DependencyProperty.Register("CornerCut", typeof(double), typeof(CutCornerBorder), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), new ValidateValueCallback(CutCornerBorder.IsCornerCutValid));
public static readonly DependencyProperty BorderBrushProperty = DependencyProperty.Register("BorderBrush", typeof(Brush), typeof(CutCornerBorder), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender, new PropertyChangedCallback(CutCornerBorder.OnClearPenCache)));
private static void OnClearPenCache(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CutCornerBorder cutCornerBorder = (CutCornerBorder)d;
cutCornerBorder.cachedPen = null;
}
private static bool IsCornerCutValid(object value)
{
/* You can add here your own validation logic */
return true;
}
private static bool IsThicknessValid(object value)
{
Thickness thickness = (Thickness)value;
/* You can add here your own validation logic */
return true
}
public double BorderThickness
{
get
{
return (double)base.GetValue(BorderThicknessProperty);
}
set
{
base.SetValue(BorderThicknessProperty, value);
}
}
public double CornerCut
{
get
{
return (double)base.GetValue(CornerCutProperty);
}
set
{
base.SetValue(CornerCutProperty, value);
}
}
public Thickness Padding
{
get
{
return (Thickness)base.GetValue(PaddingProperty);
}
set
{
base.SetValue(PaddingProperty, value);
}
}
public Brush BorderBrush
{
get
{
return (Brush)base.GetValue(BorderBrushProperty);
}
set
{
base.SetValue(BorderBrushProperty, value);
}
}
protected override void OnRender(DrawingContext dc)
{
if (BorderThickness > 0 && BorderBrush != null)
{
Pen pen = cachedPen;
if (pen == null)
{
pen = new Pen();
pen.Brush = BorderBrush;
pen.Thickness = BorderThickness;
if (BorderBrush.IsFrozen)
{
pen.Freeze();
}
cachedPen = pen;
}
if (BorderThickness > 0)
{
double num = pen.Thickness * 0.5;
/* Left */
dc.DrawLine(pen, new Point(num, CornerCut), new Point(num, RenderSize.Height - CornerCut));
/* Right */
dc.DrawLine(pen, new Point(RenderSize.Width - num, CornerCut),
new Point(RenderSize.Width - num, RenderSize.Height - CornerCut));
/* Top */
dc.DrawLine(pen, new Point(CornerCut, num), new Point(RenderSize.Width - CornerCut, num));
/* Bottom */
dc.DrawLine(pen, new Point(CornerCut, RenderSize.Height - num), new Point(RenderSize.Width - CornerCut, RenderSize.Height - num));
dc.DrawLine(pen, new Point(num, CornerCut), new Point(CornerCut, num));
dc.DrawLine(pen, new Point(RenderSize.Width - CornerCut, num), new Point(RenderSize.Width - num, CornerCut));
dc.DrawLine(pen, new Point(RenderSize.Width - num, RenderSize.Height - CornerCut),
new Point(RenderSize.Width - CornerCut, RenderSize.Height - num));
dc.DrawLine(pen, new Point(CornerCut, RenderSize.Height - num),
new Point(num, RenderSize.Height - CornerCut));
}
}
}
}
As you can see OnRender
method does the "dirty job" (by drawing the cut border). So in your XAML you can write:
<local:CutCornerBorder BorderBrush="Black" BorderThickness="3" CornerCut="40" Margin="30">
<TextBlock Text="HELLO!" FontSize="18" HorizontalAlignment="Center"
VerticalAlignment="Center" Background="Green" Margin="20" />
</local:CutCornerBorder>
I hope it can help you with your issue.

Il Vic
- 5,576
- 4
- 26
- 37