c# - WPF:如何将线条绑定(bind)到 UI 元素?

标签 c# .net wpf pixelsense

我使用此方法将 Line 绑定(bind)到两个 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 的底部绑定(bind)到另一个 ScatterViewItem 的顶部: enter image description here

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

最佳答案

你可以:

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

    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 绑定(bind),但使该行的 ZIndex 位于矩形的下方。使用这种方法可能会让您不必检测一个 ScatterViewItem 的移动方式是否需要更改转换器中使用的一侧。

关于c# - WPF:如何将线条绑定(bind)到 UI 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5009157/

相关文章:

c# - 检查 double.ToString()

c# - Catel - CommandManager 未传递 CommandParameter

c# - 全局资源未将样式应用于 xaml 中的控件

c# - 绑定(bind) DataGridView 时不应用 DefaultCellStyle 格式

c# - 为什么当我使用字符串 "&&"时,它只在表单标签上显示 "&"?

c# - Azure IoT 中心 - 可移植库中的设备注册

javascript - 每次单击按钮时如何防止 javascript 重新加载?

c# - 使用 CSWinRT 调用 .net5 windows api

c# - 长度为 2 的多个构造函数。无法与 Unity 消除歧义

c# - 获取额外的 PaperSource 详细信息