CustomControl XAML: привязка ArcSegment.Size к фактической ширине и высоте элемента управления - PullRequest
0 голосов
/ 11 июля 2020

мои товарищи-программисты!

Я искал Inte rnet и не нашел решения. Вероятно, это связано с тем, что я новичок ie в WPF. Я пытаюсь достичь следующего:

CustomControl, имеющий ArcSegment, Size которого привязан к размеру CustomControl: enter image description here

This should illustrate a wafer with dies (semiconductor industry)

So I understood that I need to use in XAML in order to construct that 'circle with notch'

My problem is that I cannot bind the ArcSegment element to CustomControl's Size. ArcSegment has Size property and CustomControl has ActualWidth & ActualHeight. I tried several approaches but neither of them worked for me.

Here is my class for CustomControl:

    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:

1 Ответ

1 голос
/ 11 июля 2020

Вы, возможно, можете использовать простую производную форму, как показано ниже. выемка.

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);
    }
}

Вы бы использовали его как любой другой элемент формы:

<local:WaferMap Stroke="Orange" StrokeThickness="3" Margin="10"/>
...