WPF列车运行图绘制功能

需求功能

1.在整个大界面下区别出一块绘制出运行图底图
2.有滚动条可以拖拽
3.可以实现放缩

思路

宽度:每天是1440min,设置2880个像素宽度,再留出60min(120像素点)作为跨日调整的需要
,再留出100个像素点作为边框。
高度:想想

前端



<Grid.ColumnDefinitions>



</Grid.ColumnDefinitions>

    <Slider Grid.Column="0" Orientation="Vertical" HorizontalAlignment="Left" Minimum="1" Value="5" x:Name="slider"/><!--提供五倍放缩-->
    <TextBlock Text= "{Binding ElementName=slider,Path=Value}" Grid.Column="2" Height="20" VerticalAlignment="Top"/>
    <ScrollViewer Name="scrollViewer" Grid.Column="1"  VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
        <Grid Name="grid" Width="3100"  Height="800"  RenderTransformOrigin="0.5,0.5">
            <Grid.LayoutTransform>
                <TransformGroup>
                    <ScaleTransform x:Name="scaleTransform"/>
                </TransformGroup>
            </Grid.LayoutTransform>
            <Line X1="10" Y1="20" X2="500" Y2="10" Stroke="Black" StrokeThickness="2"></Line>
            
            <!--<Canvas Grid.Column="0" Grid.Row="0">
                <Line X1="20" Y1="600" X2="500" Y2="10" Stroke="Black" StrokeThickness="4"></Line>
            </Canvas>-->
            
            <!--
            <Viewbox Grid.Column="0" Grid.Row="0">
                <ContentPresenter Content="I Don't know how"/>
            </Viewbox>-->
        </Grid>

    </ScrollViewer>
</Grid>
## 后端

`

namespace DrawLine
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
Point? lastCenterPositionOnTarget;//定义了三个坐标变量
Point? lastMousePositionOnTarget;
Point? lastDragPoint;//最后拉拽点

    public MainWindow()
    {

        InitializeComponent();
        scrollViewer.ScrollChanged += OnScrollViewerScrollChanged;//拉条条
        scrollViewer.MouseLeftButtonUp += OnMouseLeftButtonUp;//preview是隧道,向下
        scrollViewer.PreviewMouseLeftButtonUp += OnMouseLeftButtonUp;//路由和冒泡事件都关联,就是释放一些东西
        scrollViewer.PreviewMouseWheel += OnPreviewMouseWheel;//滚轮改变那个条条的值,只在scrollviewer中才有用

        scrollViewer.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
        scrollViewer.MouseMove += OnMouseMove;//实现拖拽

        slider.ValueChanged += OnSliderValueChanged;//最关键的,比例尺的变化
    }
    void OnMouseMove(object sender, MouseEventArgs e)
    {
        if (lastDragPoint.HasValue)//在DOWN里有值,一UP就会没值,通过这个有没有值来实现拖拽
        {
            Point posNow = e.GetPosition(scrollViewer);//获得在scrollviewer中的位置?

            double dX = posNow.X - lastDragPoint.Value.X;
            double dY = posNow.Y - lastDragPoint.Value.Y;

            lastDragPoint = posNow;

            scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - dX);
            scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - dY);
        }
    }

    void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var mousePos = e.GetPosition(scrollViewer);//在scrollviewer中的位置
        if (mousePos.X <= scrollViewer.ViewportWidth && mousePos.Y <
            scrollViewer.ViewportHeight) //make sure we still can use the scrollbars
        {
            scrollViewer.Cursor = Cursors.SizeAll;
            lastDragPoint = mousePos;
            Mouse.Capture(scrollViewer);//鼠标被这个框框捕获,不这个的话就失效了
        }
    }

    void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        lastMousePositionOnTarget = Mouse.GetPosition(grid);//获得grid中的位置?

        if (e.Delta > 0)//鼠标滚轮的改变,向前是正,向自己是负数
        {
            slider.Value += 1;
        }
        if (e.Delta < 0)
        {
            slider.Value -= 1;
        }

        e.Handled = true;//表示该操作以及处理过了。e.Handled = true;来终止传递(和隧道与冒泡事件有关)
    }

    void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        scrollViewer.Cursor = Cursors.Arrow;//松了之后变回箭头
        scrollViewer.ReleaseMouseCapture();//释放
        lastDragPoint = null;//也算是释放
    }

    void OnSliderValueChanged(object sender,
         RoutedPropertyChangedEventArgs<double> e)
    {
        scaleTransform.ScaleX = e.NewValue;
        scaleTransform.ScaleY = e.NewValue;

        var centerOfViewport = new Point(scrollViewer.ViewportWidth / 2,
                                         scrollViewer.ViewportHeight / 2);
        lastCenterPositionOnTarget = scrollViewer.TranslatePoint(centerOfViewport, grid);
    }

    void OnScrollViewerScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        if (e.ExtentHeightChange != 0 || e.ExtentWidthChange != 0)
        {
            Point? targetBefore = null;
            Point? targetNow = null;

            if (!lastMousePositionOnTarget.HasValue)
            {
                if (lastCenterPositionOnTarget.HasValue)
                {
                    var centerOfViewport = new Point(scrollViewer.ViewportWidth / 2,
                                                     scrollViewer.ViewportHeight / 2);
                    Point centerOfTargetNow =
                          scrollViewer.TranslatePoint(centerOfViewport, grid);

                    targetBefore = lastCenterPositionOnTarget;
                    targetNow = centerOfTargetNow;
                }
            }
            else
            {
                targetBefore = lastMousePositionOnTarget;
                targetNow = Mouse.GetPosition(grid);

                lastMousePositionOnTarget = null;
            }

            if (targetBefore.HasValue)
            {
                double dXInTargetPixels = targetNow.Value.X - targetBefore.Value.X;
                double dYInTargetPixels = targetNow.Value.Y - targetBefore.Value.Y;

                double multiplicatorX = e.ExtentWidth / grid.Width;
                double multiplicatorY = e.ExtentHeight / grid.Height;

                double newOffsetX = scrollViewer.HorizontalOffset -
                                    dXInTargetPixels * multiplicatorX;
                double newOffsetY = scrollViewer.VerticalOffset -
                                    dYInTargetPixels * multiplicatorY;

                if (double.IsNaN(newOffsetX) || double.IsNaN(newOffsetY))
                {
                    return;
                }

                scrollViewer.ScrollToHorizontalOffset(newOffsetX);
                scrollViewer.ScrollToVerticalOffset(newOffsetY);
            }
        }
    }
}

}
`

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值