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
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)); } }
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)}; }
精彩评论