2011-04-01 5 views
0

캔버스를 확대하거나 축소해야합니다. 그러나 확대/축소는 항상 캔버스가 아닌 화면의 중앙에 위치해야합니다. 그리고 이것은 현재 코드에서 작동하지 않습니다! 항상 캔버스의 중심으로 확대되며 현재 화면은 확대되지 않습니다. 캔버스도 움직일 수 있어야하지만 테두리에서 멀리 떨어지도록 움직여서는 안됩니다.캔버스의 뷰포트 중심으로 확대 및 축소

XAML

<Grid> 
    <Canvas HorizontalAlignment="Left" Name="canvas1" VerticalAlignment="Top"> 
    </Canvas> 
</Grid> 

를 C#

 // x & y arent the position, it's how many pixel the object should move to the left/right etc 
    public void setPosition(double x, double y) 
    { 
     Thickness t = new Thickness(canvas1.Margin.Left + x, canvas1.Margin.Top + y, 0, 0); 
     if (t.Left > 0) 
     { 
      t.Left = 0; 
     } 
     else if(t.Left < -(canvas1.Width - System.Windows.SystemParameters.PrimaryScreenWidth)) 
     { 
      t.Left = -(canvas1.Width - System.Windows.SystemParameters.PrimaryScreenWidth); 
     } 

     if (t.Top > 0) 
     { 
      t.Top = 0; 
     } 
     else if (t.Top < -(canvas1.Height - System.Windows.SystemParameters.PrimaryScreenHeight)) 
     { 
      t.Top = -(canvas1.Height - System.Windows.SystemParameters.PrimaryScreenHeight); 
     } 

     canvas1.Margin = t; 
    } 

    public void setZoom(double zoom) 
    { 
     double tempW = canvas1.Width; 
     double tempH = canvas1.Height; 

     canvas1.Width *= (1 + zoom); 
     canvas1.Height *= (1 + zoom); 

     Debug.WriteLine("tempW: " + tempW + " tempH: " + tempH + " canvas1.Width: " + canvas1.Width + " canvas1.Height: " + canvas1.Height); 

     setPosition((tempW - canvas1.Width)/2, ((tempH - canvas1.Height)/2)); 
    } 

그리고 그래 내가 거기에 물건을 ScaleTransform 비슷하지만 몇 가지 이유로이 더 성능이 좋은 것을 알고 .. 물어 해달라고 : 이것은 내가 지금까지 무엇을 가지고 나 왜!

누군가 나를 도와 줄 수 있습니까?

+0

이것이 더 높은 성능을 갖는 이유는 실제로 확대/축소하지 않기 때문입니다. 당신이 틀린 캔버스의 크기는 다른 캔버스의 크기에 영향을 미치지 않기 때문에 캔버스의 크기를 변경합니다. –

+0

저는이 Grid + Canvas가 ViewBox 안에 있다고 가정합니다. 해당 뷰 박스 자체가 ScaleTransform을 사용하고 있습니다. 뷰 박스를 건너 뛰고 ScaleTransform을 직접 사용하려고 할 수 있습니다. –

답변

1

내 팬 및 확대/축소에 대한 내 솔루션은 두 가지 모두 내 복잡한 응용 프로그램 (12000px x 12000px)에서 올바르게 작동합니다.

당신은 줌 종속성 속성 (더블)과 ScaleTransform 속성을 가질 필요가

private double m_dCurZoom = 1.0; 
public double Zoom 
{ 
    get { return m_dCurZoom; } 
    set 
    { 
     double oldzoom = m_dCurZoom; 
     if (m_dCurZoom != value) 
     { 
     m_dCurZoom = value; 
     OnPropertyChanged("Zoom"); 
     UpdateZoom(oldzoom); 
     } 
    } 
} 

private ScaleTransform m_transZoom; 
public ScaleTransform TransZoom 
{ 
    get { return m_transZoom; } 
} 

private TranslateTransform m_transPan; 

/// <summary> 
/// Gets or sets the Panning in X axis. 
/// </summary> 
public double PanX 
{ 
    get { return m_transPan.X; } 
    set 
    { 
     if (m_transPan.X != value) 
     { 
     m_transPan.X = value; 
     ResizeElementContents(); 
     } 
    } 
} 

    /// <summary> 
    /// Gets or sets the Panning in Y axis. 
    /// </summary> 
    public double PanY 
    { 
    get { return m_transPan.Y; } 
    set 
    { 
     if (m_transPan.Y != value) 
     { 
      m_transPan.Y = value; 
      ResizeElementContents(); 
     } 
    } 
    } 

는 줌을 업데이트 할 때 중심점 계산이 메소드 호출

public void UpdateZoom(double oldzoom) 
{ 
    // Are we visible? 
    if (m_root == null) 
     return; 

    // Get parent of VirtualPanel 
    FrameworkElement parent = GetRootParent(); 
    if (parent == null) 
     return; 

    // Center point of the window 
    Point ptCenter = new Point(parent.RenderSize.Width/2, parent.RenderSize.Height/2); 

    // Translate into canvas coordinates 
    ptCenter = m_root.TranslatePoint(ptCenter, m_canvas); 

    // Update the zoom 
    m_transZoom.ScaleX = m_dCurZoom; 
    m_transZoom.ScaleY = m_dCurZoom; 
    m_transPan.X -= ptCenter.X * m_dCurZoom - ptCenter.X * oldzoom; 
    m_transPan.Y -= ptCenter.Y * m_dCurZoom - ptCenter.Y * oldzoom; 

    ResizeElementContents(); 

    OnPropertyChanged("Zoom"); 
} 


/// <summary> 
    /// Calculate the transform for given zoom & region-to-display for the given root's render-size 
    /// </summary> 
    public bool ResizeElementContents() 
    { 
    FrameworkElement parent = GetRootParent(); 
    if (parent == null || m_transPan == null) 
     return false; 

    // Calculate the total region of the root 
    Rect? region = WtoHelper.CalcElementRect(Root); 
    if (region == null || region.HasValue == false) 
     return false; 

    // Scale the region to get the actal size with the zoom transformation. 
    double rgnWid = region.Value.Width * m_dCurZoom; 
    double rgnHei = region.Value.Height * m_dCurZoom; 

    // Image fits within our window width? 
    if (parent.RenderSize.Width > rgnWid) 
     m_transPan.X = (parent.RenderSize.Width - rgnWid)/2; 
    else 
    { 
     // Image needs to be resized 
     if (m_transPan.X < -(rgnWid - parent.RenderSize.Width)) 
      m_transPan.X = -(rgnWid - parent.RenderSize.Width); 
     else if (m_transPan.X > 0) 
      m_transPan.X = 0; 
    } 

    // Image fits within our window height? 
    if (parent.RenderSize.Height > rgnHei) 
     m_transPan.Y = (parent.RenderSize.Height - rgnHei)/2; 
    else 
    { 
     // Image needs to be resized 
     if (m_transPan.Y < -(rgnHei - parent.RenderSize.Height)) 
      m_transPan.Y = -(rgnHei - parent.RenderSize.Height); 
     else if (m_transPan.Y > 0) 
      m_transPan.Y = 0; 
    } 

    return true; 
    } 

I을 모든 코드를 제공하지는 말고 내가 작성한 것을 이해할 수 있다면 기초가됩니다.

자세한 정보가 필요한 경우 (이 질문은 오래된 것임을 알고 있으므로 자세한 내용은 자세히 설명하지 않습니다) 알려주세요.