WPF:如何将行绑定到UI元素?

时间:2011-02-15 20:31:10

标签: c# .net wpf pixelsense

我使用此方法将Line绑定到两个ScatterViewItems的中心:

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的顶部: enter image description here

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:3)

你可以:

  1. 使用带有视图项的边界矩形的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
    
  2. 保持相同的ActualCenter绑定,但使该行的ZIndex低于矩形的行。{1}}。使用这种方法可能使您不必检测一个ScatterViewItem是否以需要更改转换器中使用的一侧的方式移动。

答案 1 :(得分:1)

  BindingOperations.SetBinding(line, Line.X1Property, new Binding { Source = origin, Path = new PropertyPath("ActualCenter.X"),Converter=converter });

是否有理由设置转换器?