2017-10-06 121 views
2

我有一个画布(不是InkCanvas!),我可以在它上面绘制多段线。这工作得很好,但是如下面的GIF所示,出现一个巨大的问题。UWP画布绘制出界

Right side is the canvas, left side is empty space.

我的画布是一个ScrollViewer中内外的ScrollViewer是一个GridView中。

我试图抓住指针离开画布以下事件处理程序:

canvas.PointerExited += Canvas_PointerExited; 
canvas.PointerCaptureLost += Canvas_PointerCaptureLost; 

但似乎这些事件被解雇的方式太慢。

我试图使用我的画布的剪辑属性,但行为没有改变。并且UWP画布上没有“ClipToBound”属性。

我的整个视图是在Code-Behind中生成的,因为我必须在一个视图上生成多个画布。

有没有办法阻止这种行为?

EDIT1:

按照要求:我的代码更深入的了解。

的XAML页面看起来是这样的:

<Grid x:Name="BoundingGrid"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*"/> 
     <RowDefinition Height="15*"/> 
    </Grid.RowDefinitions> 
    <Grid x:Name="InkGrid" VerticalAlignment="Top" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" /> 
    <Grid x:Name="CanvasGrid" Grid.Row="1" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" VerticalAlignment="Top"/> 
</Grid> 

这都是一个页面中。

我后面的代码看起来是这样的:

我的构造函数:

public ImprovedCanvasManager(Grid boundingGrid, Grid overviewGrid, string filepath, double height) 
    { 
     drawCanvas = new Canvas(); 

     overviewGrid.Loaded += OverviewGrid_Loaded; 
     overviewGrid.SizeChanged += OverviewGrid_SizeChanged; 

     RowDefinition rd = new RowDefinition(); 
     rd.Height = new GridLength(height); 

     overviewGrid.RowDefinitions.Add(rd); 

     InitializeScrollViewer(); 

     Grid.SetRow(scroll, overviewGrid.RowDefinitions.Count); 
     Grid.SetColumn(scroll, 0); 

     scroll.Content = drawCanvas; 
     overviewGrid.Children.Add(scroll); 
     LoadImage(filepath); 
    } 

     public ImprovedCanvasManager(Grid boundingGrid, Grid overviewGrid, Grid inkToolGrid, string filepath, double height = 1000) : this(boundingGrid, overviewGrid, filepath, height) 
    { 
     AddDrawingToolsToCanvas(inkToolGrid, overviewGrid); 
     EnableDrawingOnCanvas(drawCanvas); 
    } 

我只有两个contructors使它简单为我打水的能力,并没有吸引的能力实例化画布。

这是我如何初始化我的ScrollViewer:

private void InitializeScrollViewer() 
    { 
     scroll = new ScrollViewer(); 

     scroll.VerticalAlignment = VerticalAlignment.Top; 
     scroll.VerticalScrollMode = ScrollMode.Auto; 
     scroll.HorizontalScrollMode = ScrollMode.Auto; 
     scroll.VerticalScrollBarVisibility = ScrollBarVisibility.Visible; 
     scroll.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible; 
     scroll.ZoomMode = ZoomMode.Enabled; 
     scroll.ManipulationMode = ManipulationModes.All; 

     scroll.MinZoomFactor = 1; 
     scroll.MaxZoomFactor = 3; 
    } 

这些都是代码的唯一线路,影响任何viewbuilding。

编辑2:

我的画布不填左边的周边电网,但在底部。

enter image description here

+0

对上述的一个快速响应,带星号的行定义意味着百分比。所以'15 *'实际上等于'1500%'。当你使用星星时,我强烈建议所有的值加起来一个。 '和'' – Laith

+0

折线添加到哪里?那是如何组装的? – Laith

+0

谢谢你的回答。我发现你的代码工作正常。但是我的帆布不够宽,无法填满周围的网格。因此,您的代码在顶部和底部边缘完美切割线条,而不是在左侧和右侧。我在我的queston中发布了一个截图。 – eXodiquas

回答

1

PointerMoved处理程序的代码应该是相对于画布。

private void OnPointerMoved(object sender, PointerRoutedEventArgs e) 
{ 
    var point = e.GetCurrentPoint(canvas); // <-- relative to canvas. 
    var x = point.Position.X; 
    var y = point.Position.Y; 

    x = Math.Max(x, 0); 
    y = Math.Max(y, 0); 
    x = Math.Min(canvas.ActualWidth, x); 
    y = Math.Min(canvas.ActualHeight, y); 


    // add point to polyline... 
} 

如果x/y为负数或大于画布的大小,则它们超出范围。您可以按照上面的代码将点限制在画布的边框上,也可以完全丢弃点。

+0

理论上,您的代码完美无缺。当我在画布边缘缓慢地画画时,它完美地切割线条。但如果我画得很快,我仍然可以画出界限。这些事件真的很慢吗? – eXodiquas

+0

它不应该是可能的。如果你限制点的x和y值,那么不管速度如何,它们都不应该画在画布的边界之外。你有任何影响绘图的填充/边距/变换吗?也许发布一些关于如何绘制线条的代码,我会帮你调试。 – Laith

+0

我在我的问题中增加了更多细节。我希望这些信息对你有用。也许很重要的一点是,我的画布在网格加载后首先得到它的大小,因为在围绕网格建立在视图上之前,我没有找到另一种方法来获取它的高度和宽度。 – eXodiquas