【问题标题】:Why is a Line shape on a Canvas drifting away while dragging?为什么画布上的线条形状在拖动时会漂移?
【发布时间】:2016-06-29 08:24:38
【问题描述】:

我看到一个奇怪的行为在我无法解释的 Canvas 上以线条形状拖动。 Line 形状在 Thumb DataTemplate 中,如下所示:

<DataTemplate DataType="{x:Type vm:MyLine}">
    <Thumb DragDelta="Thumb_DragDelta">
        <Thumb.Template>
            <ControlTemplate TargetType="Thumb">
                <Line Fill="LightBlue" StrokeThickness="2" Y1="{Binding Y1}" Y2="{Binding Y2}" X1="{Binding X1}" X2="{Binding X2}" Stroke="LightBlue" x:Name="Line"/>
            </ControlTemplate>
        </Thumb.Template>
    </Thumb>
</DataTemplate>

画布是ItemsPanelTemplateListBox。在ListBox.ItemContainerStyle 中没有Canvas.TopCanvas.Left 绑定或设置器。宽度和高度也没有绑定。

Canvs 上的线条正在拖动,但它偏离了鼠标位置。相当狂野和快速。

在代码后面拖拽有效果:

line.X1 += e.HorizontalChange; line.X2 += e.HorizontalChange;
line.Y1 += e.VerticalChange; line.Y2 += e.VerticalChange;

X..Y 的 setter 提升 PropertyChanged 否则 Line 不会移动。

对于Line 的正确拖动行为我应该怎么做?为什么?
Binding Mode=OneWay 没有区别。

【问题讨论】:

  • 在不绑定Xs和Ys的情况下试试。只在后面的代码中更改Xs和Ys。
  • @Miro:X,Y 是画线所必需的。
  • 但是您正在将 Ys 和 Xs 绑定到它们自己...
  • 第一个 X,Y 是 Line 形状的依赖属性。后者是数据上下文的属性。

标签: wpf wpf-controls


【解决方案1】:

事实证明,当添加到 Thumb 时,Line 形状的行为与 Ellipse 形状有些不同。 Thumb 在其 DragDelta 事件中触发鼠标 w.r.t 的总位移。开始拖动时按下左键的位置。

对于椭圆,这是可以的,因为在内部,椭圆形状的EllipseGeometry 被拉伸以填充位于 Canvas.Left、Canvas.Top、Width 和 Height 的 Canvas 上的 Rectangle。显然,总位移是动画在画布上拖动椭圆的正确值。

对于线条,在画布上拖动椭圆的正确值是两个连续的DragDelta 事件之间的位移差。根据内部LineGeometry 的 X1、X2、Y1、Y2 属性绘制一条线。其GeometryBounds 的 Rectangle 被忽略(尽管该线被剪裁到此边界之外)。然后可以将 Line 的 Canvas.Left=Canvas.Top 设置为 0,并将 Width 和 Height 设置为 Canvas 的 ActualHeight 和 ActualWidth。

也可以创建一个自己的椭圆形状,它具有中心和半径属性。这样的形状会表现得像线条形状。

我所做的是创建一个 ThumbShape 作为基类,从 MS 的 Thumb.cs 复制代码。因此,我还必须复制相应的 EventArgs 类和 EventHandler 委托。我在DragDelta 事件参数中添加了相对鼠标更改,以便我可以选择是使用相对偏移还是拖动的总偏移。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,在这个答案之后“对于一条线,在画布上拖动椭圆的正确值是两个连续 DragDelta 事件之间的位移差。”我开发了这个解决方案,为我工作,希望这对某人有帮助

     public class Connector : Thumb
    {
        private double _oldX = 0;
        private double _oldY = 0;
    
    
        public Connector()
        {
            DragDelta += Connector_DragDelta;
            DragCompleted += Connector_DragCompleted;
        }
    
        private void Connector_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            _oldX = 0;
            _oldY = 0;
        }
    
        private void Connector_DragDelta(object sender, DragDeltaEventArgs e)
        {
            Thumb thumb = e.Source as Thumb;
            DiagramConnectorViewModel viewModel = (DiagramConnectorViewModel)thumb.DataContext;
    
            double leftOffSet = _oldX - e.HorizontalChange;
            _oldX = e.HorizontalChange;
            viewModel.X1 -= leftOffSet;
            viewModel.X2 -= leftOffSet;
    
            double topOffSet = _oldY - e.VerticalChange;
            _oldY = e.VerticalChange;
            viewModel.Y1 -= topOffSet;
            viewModel.Y2 -= topOffSet;
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-03
      • 2022-01-09
      • 2011-01-01
      • 2016-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多