Why is a Line shape on a Canvas drifting away while dragging?

做~自己de王妃 提交于 2019-12-31 05:03:21

问题


I see a strange behaviour dragging in Line shape over a Canvas that I cannot explain. The Line shape is in a Thumb DataTemplate like so:

<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>

The Canvas is ItemsPanelTemplate of a ListBox. In the ListBox.ItemContainerStyle there is no Canvas.Top or Canvas.Left Binding or Setter. Also no Binding for Width and Height.

The Line on the Canvs is dragging but it drifts away from the mouse position. Fairly wild and quick.

In code behind the dragging has the effect:

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

The setters for X..Y raise PropertyChanged otherwise the Line wouldn't move.

What should I do for a proper dragging behaviour for Line and why?
Binding Mode=OneWay makes no difference.


回答1:


It turns out that the Line shape behaves somewhat different from the Ellipse shape when added to a Thumb. The Thumb fires in its DragDelta event the total displacment of the mouse w.r.t. the position where the left button was pressed when the dragging started.

For an ellipse this is ok, because internally, the EllipseGeometry of the Ellipse shape is stretched to fill Rectangle that is positioned on the Canvas with Canvas.Left, Canvas.Top, Width and Height. Apparantly the total displacement is the correct value to animate the dragging of the ellipse on the canvas.

For a Line the correct value to animate the dragging of the ellipse on the canvas is the difference of the displacement between two consecutive DragDelta events. A Line is drawn on the basis of X1, X2, Y1, Y2 properties of an internal LineGeometry. The Rectangle of its GeometryBounds are ignored (although the line is clipped beyond this border). The Line's Canvas.Left=Canvas.Top can then be set to 0 and Width and Height equal to the ActualHeight and ActualWidth of the Canvas.

One could also create an own Ellipse shape with a Center and Radius property. Such a shape then would behave like the Line shape.

What I did is create a ThumbShape as a base class, copying code from Thumb.cs of MS. Therfore I also had to copy the corresponding EventArgs classes and EventHandler delegates. I added to the DragDelta eventarguments a relative mouse change so that I can choose whether to use the relative offset or the total offset of the dragging.




回答2:


I had the same problem and after this answer "For a Line the correct value to animate the dragging of the ellipse on the canvas is the difference of the displacement between two consecutive DragDelta events." I developed this solution, worked for me, hope this helps someone

 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;

    }


来源:https://stackoverflow.com/questions/21920910/why-is-a-line-shape-on-a-canvas-drifting-away-while-dragging

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!