[英]CustomControl XAML: ArcSegment.Size binding to control's Actual Width and Height
my fellow programmers!我的程序员同胞!
I have searched the Internet and could not find a solution.我已经搜索了互联网,但找不到解决方案。 Probably this is due to me being a newbie in WPF.
这可能是因为我是 WPF 的新手。 I'm trying to achieve the following:
我正在努力实现以下目标:
CustomControl
having an ArcSegment
whose Size
is bound to the size of the CustomControl
: CustomControl
的ArcSegment
的Size
绑定到CustomControl
的大小:
This should illustrate a wafer with dies (semiconductor industry)这应该说明带有裸片的晶圆(半导体行业)
So I understood that I need to use <Path>
in XAML in order to construct that 'circle with notch'所以我明白我需要在 XAML 中使用
<Path>
来构造那个“带缺口的圆”
My problem is that I cannot bind the ArcSegment
element to CustomControl's Size
.我的问题是我无法将
ArcSegment
元素绑定到 CustomControl 的Size
。 ArcSegment
has Size
property and CustomControl
has ActualWidth
& ActualHeight
. ArcSegment
具有Size
属性,而CustomControl
具有ActualWidth
和ActualHeight
。 I tried several approaches but neither of them worked for me.我尝试了几种方法,但它们都不适合我。
Here is my class for CustomControl
:这是我用于
CustomControl
的 class :
public class WaferMap : Control
{
public static readonly DependencyProperty ActualSizeProperty = DependencyProperty.Register(
nameof(ActualSize), typeof(Size), typeof(WaferMap), new PropertyMetadata(default(Size)));
public Size ActualSize
{
get => (Size) this.GetValue(ActualSizeProperty);
set => this.SetValue(ActualSizeProperty, value);
}
public WaferMap()
{
var actualWidthPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(ActualWidthProperty, typeof(WaferMap));
actualWidthPropertyDescriptor.AddValueChanged(this, OnActualWidthOrHeightChanged);
var actualHeightPropertyDescriptor = DependencyPropertyDescriptor.FromProperty(ActualHeightProperty, typeof(WaferMap));
actualHeightPropertyDescriptor.AddValueChanged(this, OnActualWidthOrHeightChanged);
}
private void OnActualWidthOrHeightChanged(object? sender, EventArgs e)
{
this.ActualSize = new Size(ActualWidth, ActualHeight);
}
static WaferMap()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(WaferMap), new FrameworkPropertyMetadata(typeof(WaferMap)));
}
}
And the XAML Style that I use for it:我使用的 XAML 样式:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Zeiss.CdAnalizer.Ui">
<Style TargetType="local:WaferMap">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:WaferMap" >
<ControlTemplate.Resources>
<local:WaferMap x:Key="WaferMap"/>
</ControlTemplate.Resources>
<Grid DataContext="{Binding Source={StaticResource WaferMap}}">
<Path Stroke="Black" StrokeThickness="1">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="145,300">
<PathFigure.Segments>
<PathSegmentCollection>
<ArcSegment
IsLargeArc="True"
Size="{Binding Path=ActualSize, PresentationTraceSources.TraceLevel=High}"
SweepDirection="Clockwise"
Point="155,300" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style></ResourceDictionary>
Surely I'll need to bind also the StartPoint
, but first I wanted to see that simple stuff works for me.当然,我还需要绑定
StartPoint
,但首先我想看看那些简单的东西对我有用。 Unfortunately, it doesn't.不幸的是,事实并非如此。 I see this in my Output window:
我在我的 Output window 中看到了这个:
System.Windows.Data Warning: 60 : BindingExpression (hash=14976165): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=14976165): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=14976165): Attach to System.Windows.Media.ArcSegment.Size (hash=24211521)
System.Windows.Data Warning: 64 : BindingExpression (hash=14976165): Use Framework mentor <null>
System.Windows.Data Warning: 67 : BindingExpression (hash=14976165): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=14976165): Framework mentor not found
System.Windows.Data Warning: 65 : BindingExpression (hash=14976165): Resolve source deferred
System.Windows.Data Warning: 95 : BindingExpression (hash=14976165): Got InheritanceContextChanged event from ArcSegment (hash=24211521)
System.Windows.Data Warning: 67 : BindingExpression (hash=14976165): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=14976165): Framework mentor not found
System.Windows.Data Warning: 95 : BindingExpression (hash=14976165): Got InheritanceContextChanged event from ArcSegment (hash=24211521)
System.Windows.Data Warning: 67 : BindingExpression (hash=14976165): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=14976165): Framework mentor not found
System.Windows.Data Warning: 95 : BindingExpression (hash=14976165): Got InheritanceContextChanged event from ArcSegment (hash=24211521)
System.Windows.Data Warning: 67 : BindingExpression (hash=14976165): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=14976165): Framework mentor not found
System.Windows.Data Warning: 95 : BindingExpression (hash=14976165): Got InheritanceContextChanged event from ArcSegment (hash=24211521)
System.Windows.Data Warning: 67 : BindingExpression (hash=14976165): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=14976165): Framework mentor not found
System.Windows.Data Warning: 95 : BindingExpression (hash=14976165): Got InheritanceContextChanged event from ArcSegment (hash=24211521)
System.Windows.Data Warning: 67 : BindingExpression (hash=14976165): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=14976165): Found data context element: Path (hash=10232270) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=14976165): Activate with root item WaferMap (hash=14353717)
System.Windows.Data Warning: 108 : BindingExpression (hash=14976165): At level 0 - for WaferMap.ActualSize found accessor DependencyProperty(ActualSize)
System.Windows.Data Warning: 104 : BindingExpression (hash=14976165): Replace item at level 0 with WaferMap (hash=14353717), using accessor DependencyProperty(ActualSize)
System.Windows.Data Warning: 101 : BindingExpression (hash=14976165): GetValue at level 0 from WaferMap (hash=14353717) using DependencyProperty(ActualSize): Size (hash=0)
System.Windows.Data Warning: 80 : BindingExpression (hash=14976165): TransferValue - got raw value Size (hash=0)
System.Windows.Data Warning: 89 : BindingExpression (hash=14976165): TransferValue - using final value Size (hash=0)
When I say it doesn't work = when I change the size of the form nothing happens (the arc stays the same small dash).当我说它不起作用时 = 当我更改表单的大小时,什么也没有发生(弧保持相同的小破折号)。 Also, the
WaferMap.ActualSize.get
is never get called.此外,
WaferMap.ActualSize.get
永远不会被调用。 The setter is called when I change size of the form (As you can see I have registered to change event of ActualWidth
and ActualHeight
).当我更改表单的大小时调用 setter(如您所见,我已注册更改
ActualWidth
和ActualHeight
的事件)。
Thank you!谢谢!
You may perhaps use a simple derived Shape like shown below.您也许可以使用一个简单的派生形状,如下所示。
It draws an ArcSegment with a notch at the bottom center, and all you would have to do is to adjust the size of the notch.它在底部中心绘制一个带有缺口的 ArcSegment,您所要做的就是调整缺口的大小。
public class WaferMap : Shape
{
private readonly StreamGeometry geometry = new StreamGeometry();
protected override Geometry DefiningGeometry => geometry;
protected override Size MeasureOverride(Size size)
{
if (double.IsInfinity(size.Width))
{
size.Width = StrokeThickness;
}
if (double.IsInfinity(size.Height))
{
size.Height = StrokeThickness;
}
return size;
}
protected override Size ArrangeOverride(Size size)
{
var x = size.Width / 2;
var y = size.Height - StrokeThickness / 2;
var arcSize = new Size(
(size.Width - StrokeThickness) / 2, (size.Height - StrokeThickness) / 2);
using (var sgc = geometry.Open())
{
sgc.BeginFigure(new Point(x, y - 20), true, true);
sgc.LineTo(new Point(x - 10, y), true, true);
sgc.ArcTo(new Point(x + 10, y), arcSize, 0, true,
SweepDirection.Clockwise, true, true);
}
return size;
}
protected override void OnRender(DrawingContext drawingContext)
{
drawingContext.DrawGeometry(Fill, new Pen(Stroke, StrokeThickness), geometry);
}
}
You would use it like any other Shape element:您可以像使用任何其他 Shape 元素一样使用它:
<local:WaferMap Stroke="Orange" StrokeThickness="3" Margin="10"/>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.