开发者

WPF: how to bind lines to UI elements?

I use this method to bind a Line to the center of two 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") });
        }

But now I'd like to bind it from the bottom from one ScatterViewItem to the top of the another ScatterViewItem:

WPF: how to bind lines to UI elements?

How can I achieve that?


You could:

  1. Use a IValueConverter that takes the bounding rectangle of the view item and a converter parameter to specify the side to calculate the center from.

    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();
        }
    }
    

    The converter you would use would be:

    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. Keep the same ActualCenter bindings, but make the ZIndex of the line below that of the rectangles. Using this approach will likely keep you from having to detect if one ScatterViewItem moves in such a way that needs to change the side used in the converter.


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

is there a reason this wouldnt work to set the converter?

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜