C# 从形状派生的WPF自定义形状类
我正试图在WPF中创建一个自定义的楔形形状类,它派生自抽象形状类,并且能够像其他形状一样在XAML中定义它 我一直在谷歌上搜索关于如何实现这一点的完整教程,但我找到的都是关于自定义控件的内容。我想要的是创建一个楔子类,它允许我指定内半径、外半径、该楔子在360度范围内的截面数(即,如果我想在圆周围安装24个楔子,则该楔子的大小将与24个楔子的大小相同)及其位置(它将占据24个空间中的哪一个)。这些都是依赖属性,我已经注册了它们 DefiningGeometry属性调用一个方法,该方法执行计算点和绘制形状的所有逻辑 我遇到的问题是VS2010使用属性“Template”的setter自动创建了一个样式。然后,当我编译时,它会给我一个错误,说: “错误3在类型“WpfApplication1.Wedge”上找不到样式属性“Template”。第8行位置17.C:\Users\rflint\Desktop\WpfApplication1\WpfApplication1\Themes\Generic.xaml 8 17 WpfApplication1” 如果我把它注释掉,所有的东西都会编译,但是楔形块没有显示在表单上。如何实现此模板设置器属性?我需要吗 XAML:C# 从形状派生的WPF自定义形状类,c#,wpf,xaml,shape,C#,Wpf,Xaml,Shape,我正试图在WPF中创建一个自定义的楔形形状类,它派生自抽象形状类,并且能够像其他形状一样在XAML中定义它 我一直在谷歌上搜索关于如何实现这一点的完整教程,但我找到的都是关于自定义控件的内容。我想要的是创建一个楔子类,它允许我指定内半径、外半径、该楔子在360度范围内的截面数(即,如果我想在圆周围安装24个楔子,则该楔子的大小将与24个楔子的大小相同)及其位置(它将占据24个空间中的哪一个)。这些都是依赖属性,我已经注册了它们 DefiningGeometry属性调用一个方法,该方法执行计算点和
我刚刚在VS2012上试用过,效果很好,至少使用了简单的椭圆几何体:
public sealed class Wedge : Shape
{
public Double Radius
{
get { return (Double)this.GetValue(RadiusProperty); }
set { this.SetValue(RadiusProperty, value); }
}
public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register(
"Radius", typeof(Double), typeof(Wedge), new PropertyMetadata(0.0));
protected override Geometry DefiningGeometry
{
get {return new EllipseGeometry(new Point(0, 0), this.Radius, this.Radius); }
}
}
以及XAML:
<local:Wedge Radius="50" Stroke="Black" Fill="Yellow" StrokeThickness="2" Canvas.Top="100" Canvas.Left="100" />
让我为您的问题提供一个简单的解决方案:
public class Wedge : Shape
{
public Double StartAngle
{
get { return (Double)GetValue(StartAngleProperty); }
set { SetValue(StartAngleProperty, value); }
}
public static readonly DependencyProperty StartAngleProperty =
DependencyProperty.Register("StartAngle", typeof(Double), typeof(Wedge), new PropertyMetadata(0d));
public Double EndAngle
{
get { return (Double)GetValue(EndAngleProperty); }
set { SetValue(EndAngleProperty, value); }
}
public static readonly DependencyProperty EndAngleProperty =
DependencyProperty.Register("EndAngle", typeof(Double), typeof(Wedge), new PropertyMetadata(0d));
public Point Center
{
get { return (Point)GetValue(CenterProperty); }
set { SetValue(CenterProperty, value); }
}
public static readonly DependencyProperty CenterProperty =
DependencyProperty.Register("Center", typeof(Point), typeof(Wedge), new PropertyMetadata(new Point()));
public Double InnerRadius
{
get { return (Double)GetValue(InnerRadiusProperty); }
set { SetValue(InnerRadiusProperty, value); }
}
public static readonly DependencyProperty InnerRadiusProperty =
DependencyProperty.Register("InnerRadius", typeof(Double), typeof(Wedge), new PropertyMetadata(0d));
public Double OuterRadius
{
get { return (Double)GetValue(OuterRadiusProperty); }
set { SetValue(OuterRadiusProperty, value); }
}
public static readonly DependencyProperty OuterRadiusProperty =
DependencyProperty.Register("OuterRadius", typeof(Double), typeof(Wedge), new PropertyMetadata(0d));
protected override Geometry DefiningGeometry
{
get
{
StreamGeometry geometry = new StreamGeometry();
using (StreamGeometryContext context = geometry.Open())
{
Draw(context);
}
return geometry;
}
}
private void Draw(StreamGeometryContext context)
{
var isStroked = Stroke != null & Stroke != Brushes.Transparent & StrokeThickness > 0;
var isFilled = Fill != null & Fill != Brushes.Transparent;
context.BeginFigure(
GetPointOnCircle(Center, OuterRadius, StartAngle),
isFilled,
true);
context.ArcTo(
GetPointOnCircle(Center, OuterRadius, EndAngle),
new Size(OuterRadius, OuterRadius),
0,
EndAngle - StartAngle > 180,
SweepDirection.Clockwise,
isStroked,
true);
context.LineTo(GetPointOnCircle(Center, InnerRadius, EndAngle), isStroked, true);
context.ArcTo(
GetPointOnCircle(Center, InnerRadius, StartAngle),
new Size(InnerRadius, InnerRadius),
0,
EndAngle - StartAngle > 180,
SweepDirection.Counterclockwise,
isStroked,
true);
context.LineTo(GetPointOnCircle(Center, OuterRadius, StartAngle), isStroked, true);
}
private Point GetPointOnCircle(Point center, double radius, double angle)
{
var px = center.X + radius * Math.Cos(ToRadians(angle));
var py = center.Y + radius * Math.Sin(ToRadians(angle));
return new Point(px, py);
}
public double ToRadians(double angle)
{
return angle * Math.PI / 180;
}
}
形状不是
控件
,因此您将没有它的模板
属性。您可能没有设置填充
,或笔划
属性?Post XAML以便向我们展示您如何尝试在屏幕上显示楔块。您是否也可以发布定义几何体
?受保护的覆盖几何体定义几何体{get{使用(StreamGeometryContext context=Geometry.Open(){DrawWedgeGeometry(context);}返回几何体;}@ourmanflint请编辑您的问题,使其包含此代码并正确格式化,而不是将其作为注释发布。还请包含完整代码和XAML。顺便说一句,如果您在谷歌上搜索“支持数据绑定的WPF饼图”,则该项目包含一个名为“Piepeat”的形状类,它似乎完全符合您的要求。
<local:Wedge Radius="50" Stroke="Black" Fill="Yellow" StrokeThickness="2" Canvas.Top="100" Canvas.Left="100" />
public class Wedge : Shape
{
public Double StartAngle
{
get { return (Double)GetValue(StartAngleProperty); }
set { SetValue(StartAngleProperty, value); }
}
public static readonly DependencyProperty StartAngleProperty =
DependencyProperty.Register("StartAngle", typeof(Double), typeof(Wedge), new PropertyMetadata(0d));
public Double EndAngle
{
get { return (Double)GetValue(EndAngleProperty); }
set { SetValue(EndAngleProperty, value); }
}
public static readonly DependencyProperty EndAngleProperty =
DependencyProperty.Register("EndAngle", typeof(Double), typeof(Wedge), new PropertyMetadata(0d));
public Point Center
{
get { return (Point)GetValue(CenterProperty); }
set { SetValue(CenterProperty, value); }
}
public static readonly DependencyProperty CenterProperty =
DependencyProperty.Register("Center", typeof(Point), typeof(Wedge), new PropertyMetadata(new Point()));
public Double InnerRadius
{
get { return (Double)GetValue(InnerRadiusProperty); }
set { SetValue(InnerRadiusProperty, value); }
}
public static readonly DependencyProperty InnerRadiusProperty =
DependencyProperty.Register("InnerRadius", typeof(Double), typeof(Wedge), new PropertyMetadata(0d));
public Double OuterRadius
{
get { return (Double)GetValue(OuterRadiusProperty); }
set { SetValue(OuterRadiusProperty, value); }
}
public static readonly DependencyProperty OuterRadiusProperty =
DependencyProperty.Register("OuterRadius", typeof(Double), typeof(Wedge), new PropertyMetadata(0d));
protected override Geometry DefiningGeometry
{
get
{
StreamGeometry geometry = new StreamGeometry();
using (StreamGeometryContext context = geometry.Open())
{
Draw(context);
}
return geometry;
}
}
private void Draw(StreamGeometryContext context)
{
var isStroked = Stroke != null & Stroke != Brushes.Transparent & StrokeThickness > 0;
var isFilled = Fill != null & Fill != Brushes.Transparent;
context.BeginFigure(
GetPointOnCircle(Center, OuterRadius, StartAngle),
isFilled,
true);
context.ArcTo(
GetPointOnCircle(Center, OuterRadius, EndAngle),
new Size(OuterRadius, OuterRadius),
0,
EndAngle - StartAngle > 180,
SweepDirection.Clockwise,
isStroked,
true);
context.LineTo(GetPointOnCircle(Center, InnerRadius, EndAngle), isStroked, true);
context.ArcTo(
GetPointOnCircle(Center, InnerRadius, StartAngle),
new Size(InnerRadius, InnerRadius),
0,
EndAngle - StartAngle > 180,
SweepDirection.Counterclockwise,
isStroked,
true);
context.LineTo(GetPointOnCircle(Center, OuterRadius, StartAngle), isStroked, true);
}
private Point GetPointOnCircle(Point center, double radius, double angle)
{
var px = center.X + radius * Math.Cos(ToRadians(angle));
var py = center.Y + radius * Math.Sin(ToRadians(angle));
return new Point(px, py);
}
public double ToRadians(double angle)
{
return angle * Math.PI / 180;
}
}