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

发布于 2024-10-17 19:55:28 字数 1039 浏览 4 评论 0原文

我使用此方法将一条 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 的顶部: 在此处输入图像描述

我怎样才能实现这一目标?

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

How can I achieve that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你是年少的欢喜 2024-10-24 19:55:28

您可以:

  1. 使用一个 IValueConverter 来获取视图项的边界矩形和一个转换器参数来指定计算中心的一侧。

    public enum MidpointSide { None, Left, Top, Right, Bottom }
    
    公共类 MidpointConverter :IValueConverter
    {
        私有布尔返回Y;
        公共 MidpointConverter(bool returnY)
        {
            this.returnY = returnY;
        }
    
        公共对象转换(对象值,类型targetType,
            对象参数、CultureInfo 文化)
        {
            var scatter = 值作为 ScatterViewItem;
            var side = (MidpointSide)参数;
            var center = scatter.ActualCenter;
            var halfW = scatter.ActualWidth / 2.0;
            var halfH = scatter.ActualHeight / 2.0;
    
            点点=空;
            开关(侧面)
            {
            案例中点侧.左:
                点 = 新点(center.X - halfW, center.Y);
                休息;
            案例中点侧.顶部:
                点 = 新点(center.X, center.Y - halfH);
                休息;
            案例中点侧.右:
                点 = 新点(center.X + halfW, center.Y);
                休息;
            案例中点侧.底部:
                点 = 新点(中心.X, 中心.Y + halfH);
                休息;
            默认:
                返回空值;
            }
    
            返回这个.returnY ?点.Y : 点.X;
        }
    
        公共对象ConvertBack(对象值,类型targetType,
            对象参数、CultureInfo 文化)
        {
            抛出新的NotImplementedException();
        }
    }
    

    您将使用的转换器是:

    var x = new MidpointConverter(false), y = MidpointConverter(true);
    
    BindingOperations.SetBinding(line, Line.X1Property,
        新的 Binding { Source = origin, Converter = x, ConverterParameter = MidpointSide.Bottom });
    BindingOperations.SetBinding(line, Line.Y1Property,
        新的 Binding { Source = origin, Converter = y, ConverterParameter = MidpointSide.Bottom });
    
    // 绝对比仅仅改变 `ZIndex` 更重要
    // 你遇到了无法绑定'start'和'end'的问题
    // 一行中,只有 X1/Y1 和 X2/Y2 使此转换器参与其中
    
  2. 保留相同的ActualCenter绑定,但将该行的ZIndex设置在矩形的下面。使用这种方法可能会让您不必检测一个 ScatterViewItem 的移动方式是否需要更改转换器中使用的一侧。

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.

无戏配角 2024-10-24 19:55:28
  BindingOperations.SetBinding(line, Line.X1Property, new Binding { Source = origin, Path = new PropertyPath("ActualCenter.X"),Converter=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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文