开发者

WPF Binding to Point in a BezierSegment

I have a viewmodel class which contains double X and a double Y variable and I would like to bind this to a BezierSegment and it seems not to work here is my code...

  public class TestViewModel:ViewModelBase
{
   public TestViewModel()
   {
       TStart = new TPoint {X=20.0,Y=45.0 };
       TEnd = new TPoint { X = 200.0, Y = 450.0 };

   }
    public TPoint TStart { get; set; }
    public TPoint TEnd { get; set; }

}


public class TPoint:ViewModelBase
{

    private double _X;
    public double X
    {
        get { return _X; }
        set
        {
            if (_X != value)
            {
                _X = value;
                RaisePropertyChanged("X");
            }
        }
    }

    private double _Y;
    public double Y
    {
        get { return _Y; }
        set
        {
            if (_Y != value)
            {
                _Y = value;
                RaisePropertyChanged("Y");
            }
        }
    }


}

}

and the XAML

 <Window.DataContext>
    <vm:TestViewModel />
</Window.DataContext>
<Grid>
    <Path Stroke="Black" StrokeThickness="3">
        <Path.Data>
            <PathGeometry>
                <PathGeometry.Figures>
                    <PathFigureCollection>
                        <PathFigure>
                            <PathFigure.Segments>
                                <PathSegmentCollection>
                   开发者_StackOverflow社区                 <BezierSegment>
                                        <BezierSegment.Point1>
                                            <Point X="{Binding TStart.X}" Y="{Binding TStart.Y}" />
                                        </BezierSegment.Point1>
                                        <BezierSegment.Point3>
                                            <Point X="{Binding TEnd.X}" Y="{Binding TEnd.Y}" />
                                        </BezierSegment.Point3>
                                    </BezierSegment>
                                </PathSegmentCollection>
                            </PathFigure.Segments>
                        </PathFigure>
                    </PathFigureCollection>
                </PathGeometry.Figures>
            </PathGeometry>
        </Path.Data>
    </Path>
</Grid>

I get an error that binding for X and Y can only be defined for DependencyProperties of a DependencyObject....

I do not want depend on the Windows Class Point ... although this would'nt even work for this example.

Can somebody tell my how I can bind my own point coordinates to BezierSegemnt Point1 Point2 Point3?


You would have to do it like this:

public class TPoint:ViewModelBase
{

    private double _X;
    public double X
    {
        get { return _X; }
        set
        {
            if (_X != value)
            {
                _X = value;
                RaisePropertyChanged("X");
                RaisePropertyChanged("P");
            }
        }
    }

    private double _Y;
    public double Y
    {
        get { return _Y; }
        set
        {
            if (_Y != value)
            {
                _Y = value;
                RaisePropertyChanged("Y");
                RaisePropertyChanged("P");
            }
        }
    }

    public Point P { get { return new Point(X,Y);}}    
}

and in the XAML:

<Window.DataContext>
    <vm:TestViewModel />
</Window.DataContext>
<Grid>
    <Path Stroke="Black" StrokeThickness="3">
        <Path.Data>
            <PathGeometry>
                <PathGeometry.Figures>
                    <PathFigureCollection>
                        <PathFigure>
                            <PathFigure.Segments>
                                <PathSegmentCollection>
                                    <BezierSegment Point1="{Binding TStart.P}" Point3="{Binding TEnd.P}"/>
                                </PathSegmentCollection>
                            </PathFigure.Segments>
                        </PathFigure>
                    </PathFigureCollection>
                </PathGeometry.Figures>
            </PathGeometry>
        </Path.Data>
    </Path>
</Grid>

let me know if it worked, I'm nowhere near a development environment


  1. Wrapper for point --> class BindingPoint with implementation of INotifyPropertyChanged interface

    public class BindingPoint : INotifyPropertyChanged
    {
        private Point point;
    
        public BindingPoint(double x, double y)
        {
            point = new Point(x, y);
        }
    
        public double X
        {
            get { return point.X; }
            set
            {
                point.X = value;
                OnPropertyChanged();
                OnPropertyChanged("Point");
            }
        }
    
        public double Y
        {
            get { return point.Y; }
            set
            {
                point.Y = value;
                OnPropertyChanged();
                OnPropertyChanged("Point");
            }
        }
    
        public Point Point
        {
            get { return point; }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
  2. Binding to BezierSegment:

    private Path DefineBezierSegment(BindingPoint startPoint, BindingPoint endPoint, BindingPoint startBezierPoint, BindingPoint endBezierPoint)
    {
        BezierSegment spline = new BezierSegment {IsStroked = true};
    
        var b = new Binding("Point")
        {
            Source = startBezierPoint,
            Mode = BindingMode.TwoWay
        };
        BindingOperations.SetBinding(spline, BezierSegment.Point1Property, b);
    
        b = new Binding("Point")
        {
            Source = endBezierPoint,
            Mode = BindingMode.TwoWay
        };
        BindingOperations.SetBinding(spline, BezierSegment.Point2Property, b);
    
        b = new Binding("Point")
        {
            Source = endPoint,
            Mode = BindingMode.TwoWay
        };
        BindingOperations.SetBinding(spline, BezierSegment.Point3Property, b);
    
        var pColl = new PathSegmentCollection {spline};
    
        var pFig = new PathFigure(StartPort.Origin.Point, pColl, false);
    
        b = new Binding("Point")
        {
            Source = startPoint,
            Mode = BindingMode.TwoWay
        };
        BindingOperations.SetBinding(pFig, PathFigure.StartPointProperty, b);
    
        var pfColl = new PathFigureCollection { pFig };
    
        return new Path() {Data = new PathGeometry(pfColl)};
    }
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜