简体   繁体   English

CustomControl XAML:ArcSegment.Size 绑定到控件的实际宽度和高度

[英]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 : CustomControlArcSegmentSize绑定到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具有ActualWidthActualHeight 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(如您所见,我已注册更改ActualWidthActualHeight的事件)。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM