2016-09-25 3 views
1

C#에서 행렬 변환을 사용하여 캔버스 확대/축소 기능을 구현하려고합니다. 하나의 특정 지점을 확대 할 수 있지만 원본 스케일 (원래 스케일로 제한됨)로 축소하는 동안 캔버스의 위치가 바뀝니다 (창 밖으로). 원래 위치로 축소하고 싶습니다. 누구든지 도와 줄 수 있습니까?C# 캔버스 확대/축소 기능 문제? 매트릭스 변환을 사용하여 점을 확대 한 후 원래 위치로 축소 할 수 없습니다.

찾아주세요 아래 코드 :

<ScrollViewer Name="C1_S" Grid.Row="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" VerticalAlignment="Bottom" Grid.ColumnSpan="2" > 
        <Canvas Name="canvas_core0" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="600" Width="1000000" MouseWheel="Canvas_MouseWheel" ClipToBounds="True" > 
         <Canvas.Background> 
          <DrawingBrush TileMode="Tile" Viewport="0,20,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> 
         <Canvas.RenderTransform> 
          <MatrixTransform/> 
         </Canvas.RenderTransform> 
        </Canvas> 
       </ScrollViewer> 

C# 코드 :`

 private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e) 
    { 
     var element = sender as UIElement; 
     var position = e.GetPosition(element); 
     if(e.Delta>0) 
     { 
      previousposition = position; 
     } 
     var transform = element.RenderTransform as MatrixTransform; 
     var matrix = transform.Matrix; 
     scrollcountprevious = scrollcountcurrent; 
     scrollcountcurrent = scrollcountcurrent + e.Delta; 
     // var scale1 = scrollcountcurrent > scrollcountprevious ? 1.1 : scrollcountcurrent <scrollcountprevious0 ? 1.0 : (1.0/1.1); // choose appropriate scaling factor 
     var scale1=1.0; 
     if (scrollcountcurrent > scrollcountprevious) 
     { 
      scale1 = 1.1; 
      matrix.ScaleAtPrepend(scale1, scale1, position.X, position.Y); 
      transform.Matrix = matrix; 
     } 
     else if (scrollcountcurrent < scrollcountprevious&&scrollcountcurrent>=0) 
     { 
      scale1 = 1/1.1; 
      matrix.ScaleAtPrepend(scale1, scale1, previousposition.X, previousposition.Y); 
     transform.Matrix = matrix; 

     } 
     else 
     { 
      scale1 = 1; 
      scrollcountcurrent = 0; 
      matrix.ScaleAtPrepend(scale1, scale1, previousposition.X, previousposition.Y); 
      transform.Matrix = matrix; 
     } 

    } 
+0

@ 클레멘스 아래 xaml을 찾으십시오. –

+0

@Clemens .. 죄송합니다. 변경했습니다. –

답변

0

난 당신이 정확히 무엇을 달성하고 싶은지 이해한다면 확실하지. 또한, ScrollViewer에 캔버스가 있으면 작업이 엉망이 될 수 있습니다.

그러나 아마이 마우스 휠 처리기 당신이 원하는 것을 :

private double scale = 1; 

private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e) 
{ 
    var element = (UIElement)sender; 
    var position = e.GetPosition(element); 
    var matrix = Matrix.Identity; 

    scale = Math.Max(e.Delta > 0 ? scale * 1.1 : scale/1.1, 1.0); 
    matrix.ScaleAt(scale, scale, position.X, position.Y); 

    ((MatrixTransform)element.RenderTransform).Matrix = matrix; 
} 

도에서 ScrollViewer에서 캔버스의 실제 크기를 확장하기 위해, 자사의 LayoutTransform 대신 RenderTransform의 확장 :

<Canvas.LayoutTransform> 
    <MatrixTransform/> 
</Canvas.LayoutTransform> 

private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e) 
{ 
    var element = (FrameworkElement)sender; 
    var position = e.GetPosition(element); 
    var matrix = Matrix.Identity; 

    scale = Math.Max(e.Delta > 0 ? scale * 1.1 : scale/1.1, 1.0); 
    matrix.ScaleAt(scale, scale, position.X, position.Y); 

    ((MatrixTransform)element.LayoutTransform).Matrix = matrix; 
} 
+0

완벽하게 작동하지만 캔버스의 스크롤 막대는 새 값으로 조정되지 않습니다. scaletransform을 사용하려고했지만 작동하지 않습니다. –

+0

RenderTransform 대신 LayoutTransform을 사용하십시오. – Clemens

+0

완벽하게 ... ... !!! :) –