c# - 使用 ScaleTransform 缩放画布时,ScrollViewer 不显示所有内容
问题描述
我在 ScrollViewer 中有两个 Canvas 面板。一个是主画布,在其背景上绘制了一个网格形状。然后我有两个 ItemsControl。第一个 ItemsControl 将 Stackpanel 作为其具有水平方向的 ItemsPanel。第二个 ItemsControl 将 Canvas 作为其面板。在此画布上,我在 Itemscontrol 的 DataTemplate 中绘制 Line 对象。此画布上有 PreviewMouseWheel 事件。在事件处理程序中,我正在缩放这个正在缩放 Line 对象的画布。此画布的宽度绑定到 ViewModel 属性 CanvasWidth。这也将改变外部画布的宽度,因为它的宽度也绑定到 ViewModel 属性 CanvasWidth。当 PreviewMouseWheel 被触发时,我将在主 Canvas 上添加更多网格线。我有 TextBlock 作为 ItemsSource 的 DataTemplate。在动物园之前,最后一个TextBlock的内容是14260。放大后应该保持14260。但是连续两个TextBlock的步长值应该减小。现在我无法通过 ScrollViewer 查看全部内容。减小了所需的步长,但通过 Scrollviewer 无法看到绘制的新网格线。我知道有内容。但我无法访问它。滚动查看器没有显示它。
<Grid x:Name="grid1" >
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<ScrollViewer Name="scrollViewer" HorizontalScrollBarVisibility="Auto" Grid.Row="1" Grid.Column="3" Margin="10,10,0,10" >
<Canvas Name="back_canvas" Height="12000" Width="{Binding CanvasWidth}" Margin="0,0,10,0" >
<Canvas.Background>
<DrawingBrush TileMode="Tile" Viewport="0,0,40,40" ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,50,50"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Gray" Thickness="1"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Canvas.Background>
<ItemsControl ItemsSource="{Binding TimeAxis}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Margin="0,0,3,0" Width="37" Background="GreenYellow" >
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding Lines}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Height="12000" Background="Transparent" Name="front_canvas"
PreviewMouseWheel="OnPreviewMouseWheel"
Width="{Binding CanvasWidth, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
</Line>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
</ScrollViewer>
</Grid>
private void UpdateGraph(Canvas canvas, double deltaValue)
{
List<MarkerView> markers = new List<MarkerView>();
scaleFactor += deltaValue;
double tempScale = scaleFactor;
if (scaleFactor < 1.0)
{
scaleFactor = 1.0;
}
if (scaleFactor > maximumScale)
{
scaleFactor = maximumScale;
}
if (tempScale > 0)
{
totalSamples = graphVM.maxSignalLength;
maximumCanvasWidth = totalSamples * maximumDeltaDistance;
if(scaleFactor<=maximumDeltaDistance)
{
ScaleTransform scaleTransform = new ScaleTransform(scaleFactor, 1);
canvas.RenderTransform = scaleTransform;
verticalLines.ForEach(x =>
{
x.RenderTransformOrigin = new Point(1, 1);
x.RenderTransform = new ScaleTransform(1 / scaleTransform.ScaleX, 1 / scaleTransform.ScaleY);
});
if (deltaValue < 0)
{
graphVM.CanvasWidth = graphVM.InitialCanvasWidth * tempScale;
}
else
{
if (graphVM.InitialCanvasWidth * scaleFactor > maximumCanvasWidth)
graphVM.CanvasWidth = maximumCanvasWidth;
else
graphVM.CanvasWidth = graphVM.InitialCanvasWidth * scaleFactor;
}
graphVM.ResetLabels();
DeltaDistance = canvas.Width / totalSamples;
MarkerView markerRed =
UIHelperView.FindChild<MarkerView>(Application.Current.MainWindow, "splitterRed");
MarkerView markerGreen =
UIHelperView.FindChild<MarkerView>(Application.Current.MainWindow, "splitterGreen");
markers.Add(markerRed);
markers.Add(markerGreen);
// Move Markers with zooming
foreach (MarkerView marker in markers)
{
marker.Delta = DeltaDistance; // after zooming if you move the marker then this value will be used to get correct position
Canvas.SetLeft(marker, marker.XPosition * DeltaDistance);
}
markers.Clear();
}
}
}
这是输出图片https://imgur.com/a/7WTrBoc 这是放大的输出https://imgur.com/C7SCOSJ
解决方案
RenderTransform 不影响控件的实际宽度/高度。尝试改用 LayoutTransform。
推荐阅读
- reactjs - React-Redux - How to redirect the page after storing the data in redux store?
- r - How to import a graph from Cytoscape to R?
- javascript - 在传递下一个数组索引之前删除每个字母?
- python - 如何在 IF 中使用结果来吐出 True/False?
- c# - How to call a function from razorview to cshtml.cs
- github-pages - Github 环境
- svelte - 如何在 Svelte 中动态渲染组件?
- excel - Send all Due to date and names in one email
- javascript - 在 Javascript 类中完成 Async Promise 时出现问题
- r - R:删除图表中没有数据(NA)的范围x轴