Как добавить невидимый слой в линию - PullRequest
0 голосов
/ 27 августа 2011

У меня есть форма линии, для которой я реализовал двойной щелчок, однако линия слишком тонкая.Я хотел бы добавить прозрачный белый отступ вокруг него, чтобы его не нужно было нажимать точно в строке.

Я действительно не хочу увеличивать толщину обводки, и мне бы хотелось, чтобы она оставалась в форме, поскольку я не хочу помещать ее в элемент управления содержимым или в рамку.

Ответы [ 3 ]

5 голосов
/ 27 августа 2011

Один из способов сделать это - переопределить стандартное Тестирование попадания этой строки. К сожалению, класс Line в WPF запечатан, что я лично считаю преступным: -)

Вот фрагмент кода, который воспроизводит поведение Line, но в другом классе, и определяет свойство Tolerance (значение по умолчанию 5). Не стесняйтесь проверить это:

using System.ComponentModel;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace MyNamespace
{
    public class HitTolerantLine : Shape
    {
        public static readonly DependencyProperty X1Property = DependencyProperty.Register("X1", typeof(double), typeof(Line), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(IsDoubleFinite));
        public static readonly DependencyProperty X2Property = DependencyProperty.Register("X2", typeof(double), typeof(Line), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(IsDoubleFinite));
        public static readonly DependencyProperty Y1Property = DependencyProperty.Register("Y1", typeof(double), typeof(Line), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(IsDoubleFinite));
        public static readonly DependencyProperty Y2Property = DependencyProperty.Register("Y2", typeof(double), typeof(Line), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(IsDoubleFinite));
        public static readonly DependencyProperty ToleranceProperty = DependencyProperty.Register("Tolerance", typeof(double), typeof(Line), new FrameworkPropertyMetadata(5.0), new ValidateValueCallback(IsDoubleFinite));

        private LineGeometry _geometry;
        private static readonly Pen _strokePen;

        static HitTolerantLine()
        {
            _strokePen = new Pen(Brushes.Black, 1.0);
            _strokePen.Freeze();
        }

        protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
        {
            HitTestResult res = base.HitTestCore(hitTestParameters);

            // didn't hit? let's add some tolerance
            if ((res == null) && (_geometry != null) && (Tolerance > 0))
            {
                if (_geometry.StrokeContains(_strokePen, hitTestParameters.HitPoint, Tolerance, ToleranceType.Absolute))
                {
                    res = new PointHitTestResult(this, hitTestParameters.HitPoint);
                }
            }
            return res;
        }

        protected virtual void DefineGeometry()
        {
            Point startPoint = new Point(X1, Y1);
            Point endPoint = new Point(X2, Y2);
            _geometry = new LineGeometry(startPoint, endPoint);
        }

        protected override Size MeasureOverride(Size constraint)
        {
            DefineGeometry();
            return base.MeasureOverride(constraint);
        }

        protected static bool IsDoubleFinite(object o)
        {
            double d = (double)o;
            return (!double.IsInfinity(d) && !double.IsNaN(d));
        }

        protected override Geometry DefiningGeometry
        {
            get
            {
                return _geometry;
            }
        }

        public double Tolerance
        {
            get
            {
                return (double)base.GetValue(ToleranceProperty);
            }
            set
            {
                base.SetValue(ToleranceProperty, value);
            }
        }

        [TypeConverter(typeof(LengthConverter))]
        public double X1
        {
            get
            {
                return (double) base.GetValue(X1Property);
            }
            set
            {
                base.SetValue(X1Property, value);
            }
        }

        [TypeConverter(typeof(LengthConverter))]
        public double X2
        {
            get
            {
                return (double) base.GetValue(X2Property);
            }
            set
            {
                base.SetValue(X2Property, value);
            }
        }

        [TypeConverter(typeof(LengthConverter))]
        public double Y1
        {
            get
            {
                return (double) base.GetValue(Y1Property);
            }
            set
            {
                base.SetValue(Y1Property, value);
            }
        }

        [TypeConverter(typeof(LengthConverter))]
        public double Y2
        {
            get
            {
                return (double) base.GetValue(Y2Property);
            }
            set
            {
                base.SetValue(Y2Property, value);
            }
        }
    }
}
1 голос
/ 27 августа 2011

Область заполнения не активна.

Единственный способ, которым я могу думать, учитывая ваши ограничения, это увеличить толщину обводки и сделать так, чтобы кисть обводки была градиентом прозрачного цвета и видимого цвета

0 голосов
/ 27 августа 2011

Нарисуйте прозрачную линию сверху с большим StrokeThickness и примените к нему поведение двойного щелчка.

...