需求功能
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);
}
}
}
}
}
`