WPF:如何将行绑定到UI元素?
我使用此方法将Line绑定到两个ScatterViewItem的中心:
private void BindLineToScatterViewItems(Shape line, ScatterViewItem origin, ScatterViewItem destination) { // Bind line.(X1,Y1) to origin.ActualCenter BindingOperations.SetBinding(line, Line.X1Property, new Binding { Source = origin, Path = new PropertyPath("ActualCenter.X") }); BindingOperations.SetBinding(line, Line.Y1Property, new Binding { Source = origin, Path = new PropertyPath("ActualCenter.Y") }); // Bind line.(X2,Y2) to destination.ActualCenter BindingOperations.SetBinding(line, Line.X2Property, new Binding { Source = destination, Path = new PropertyPath("ActualCenter.X") }); BindingOperations.SetBinding(line, Line.Y2Property, new Binding { Source = destination, Path = new PropertyPath("ActualCenter.Y") }); }
但是现在我想将它从底部从一个ScatterViewItem绑定到另一个ScatterViewItem的顶部:
我怎样才能做到这一点?
你可以:
-
使用
IValueConverter
获取视图项的边界矩形和转换器参数以指定计算中心的边。public enum MidpointSide { None, Left, Top, Right, Bottom } public class MidpointConverter : IValueConverter { private bool returnY; public MidpointConverter(bool returnY) { this.returnY = returnY; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var scatter = value as ScatterViewItem; var side = (MidpointSide)parameter; var center = scatter.ActualCenter; var halfW = scatter.ActualWidth / 2.0; var halfH = scatter.ActualHeight / 2.0; Point point = null; switch (side) { case MidpointSide.Left: point = new Point(center.X - halfW, center.Y); break; case MidpointSide.Top: point = new Point(center.X, center.Y - halfH); break; case MidpointSide.Right: point = new Point(center.X + halfW, center.Y); break; case MidpointSide.Bottom: point = new Point(center.X, center.Y + halfH); break; default: return null; } return this.returnY ? point.Y : point.X; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
您将使用的转换器将是:
var x = new MidpointConverter(false), y = MidpointConverter(true); BindingOperations.SetBinding(line, Line.X1Property, new Binding { Source = origin, Converter = x, ConverterParameter = MidpointSide.Bottom }); BindingOperations.SetBinding(line, Line.Y1Property, new Binding { Source = origin, Converter = y, ConverterParameter = MidpointSide.Bottom }); // Definitely more heavyweight than just changing the `ZIndex` // You run into the problem that you can't bind the 'start' and 'end' // of a line, only X1/Y1 and X2/Y2 making this converter involved
-
保持相同的
ActualCenter
绑定,但使行的ZIndex
低于矩形的ZIndex
。 使用这种方法可能使您不必检测一个ScatterViewItem
是否以需要更改转换器中使用的一侧的方式移动。
BindingOperations.SetBinding(line, Line.X1Property, new Binding { Source = origin, Path = new PropertyPath("ActualCenter.X"),Converter=converter });
是否有理由设置转换器?