2012-05-13 6 views
2

я работаю с Silverlight Изменение масштаба 5,Странный акт холста, когда масштаб/Увеличить Silverlight

Моя идея, чтобы увеличить в соответствии с положением мыши на холсте, а также возможность перетащить этот холст,

Проблема у меня, когда масштаб меньше 1, около 0,6 или 0,5, указывает на угол холста и колеса вверх, холст изменит свое положение или «прыжок», любая помощь, пожалуйста?

этих двух фотографий описывают состояние до этого после:

Before ZOOM

After Zoom

У меня есть следующий код XAML:

<Grid x:Name="LayoutRoot" Background="White"> 
    <ScrollViewer x:Name="sv" Margin="0,0,0,76" ScrollViewer.VerticalScrollBarVisibility="Disabled" Background="#FFE3E7F1"> 
     <Canvas x:Name="grd" Height="394" Width="630"> 
      <Canvas x:Name="cvs" Background="White" MouseWheel="cvs_MouseWheel" MouseLeftButtonDown="cvs_MouseLeftButtonDown" MouseLeftButtonUp="cvs_MouseLeftButtonUp" MouseMove="cvs_MouseMove" Height="391" Canvas.Left="2" Canvas.Top="1" Width="625"> 
       <Canvas.Effect> 
        <DropShadowEffect ShadowDepth="0"/> 
       </Canvas.Effect> 
       <Rectangle Height="70" Canvas.Left="155" Canvas.Top="58" Width="79" Fill="#FFFFBFBF"/> 
       <Rectangle Height="70" Canvas.Left="544" Canvas.Top="126" Width="79" Fill="#FF8B92FF"/> 
      </Canvas> 
     </Canvas> 
    </ScrollViewer> 
</Grid> 

и вот C#:

public partial class MainPage : UserControl 
{ 
    CompositeTransform canvasTransform = new CompositeTransform(); 
    bool canDragCanvas; 
    double mouseRelatedPositionX = 0; 
    double mouseRelatedPositionY = 0; 
    public MainPage() 
    { 
     // Required to initialize variables 
     InitializeComponent(); 
    } 

    private void cvs_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) 
    { 
     var scaleFactor = 0.2*(e.Delta < 0?-1:1); 
     var centerX = e.GetPosition(cvs).X; 
     var centerY = e.GetPosition(cvs).Y; 
     if (centerX > cvs.ActualWidth * canvasTransform.ScaleX || centerX < 0 || centerY > cvs.ActualHeight * canvasTransform.ScaleY || centerY < 0) 
     { 
      centerX = cvs.ActualWidth/2; 
      centerY = cvs.ActualHeight/2; 
     } 
     canvasTransform.CenterX = centerX; 
     canvasTransform.CenterY = centerY; 
     canvasTransform.ScaleX += scaleFactor; 
     canvasTransform.ScaleY += scaleFactor; 
     cvs.RenderTransform = canvasTransform; 
    } 

    private void cvs_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 
     canDragCanvas = true; 
     mouseRelatedPositionX = e.GetPosition(cvs).X; 
     mouseRelatedPositionY = e.GetPosition(cvs).Y; 
    } 

    private void cvs_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 
     canDragCanvas = false; 
    } 

    private void cvs_MouseMove(object sender, System.Windows.Input.MouseEventArgs e) 
    { 
     if(!canDragCanvas) return; 
     var leftValueToAdd = e.GetPosition(cvs).X - mouseRelatedPositionX; 
     var topValueToAdd = e.GetPosition(cvs).Y - mouseRelatedPositionY; 
     UpdateCanvasPosition(leftValueToAdd*canvasTransform.ScaleX, topValueToAdd*canvasTransform.ScaleX); 
    } 

    void UpdateCanvasPosition(double leftValueToAdd,double topValueToAdd) 
    { 
     var leftOffset = canvasTransform.CenterX - canvasTransform.CenterX * canvasTransform.ScaleX; 
     var rightOffset = (cvs.ActualWidth - canvasTransform.CenterX) - (cvs.ActualWidth - canvasTransform.CenterX) * canvasTransform.ScaleX; 
     var topOffset = canvasTransform.CenterY - canvasTransform.CenterY * canvasTransform.ScaleY; 
     var bottomOffset = (cvs.ActualHeight - canvasTransform.CenterY) - (cvs.ActualHeight - canvasTransform.CenterY) * canvasTransform.ScaleY; 

     var canvasLeftInBorders = Canvas.GetLeft(cvs)+ leftValueToAdd + leftOffset > 0; 
     var canvasRightInBorders = Canvas.GetLeft(cvs) + cvs.ActualWidth * canvasTransform.ScaleX + leftValueToAdd + leftOffset < grd.ActualWidth; 
     var canvasTopInBorders = Canvas.GetTop(cvs) + topValueToAdd + topOffset > 0; 
     var canvasBottomInBorders = Canvas.GetTop(cvs) + cvs.ActualHeight * canvasTransform.ScaleY + topValueToAdd + topOffset < grd.ActualHeight; 

     if (leftValueToAdd > 0) 
     { 
      if (canvasLeftInBorders) 
       leftValueToAdd = 0; 
     } 
     else if (leftValueToAdd < 0) 
      if (canvasRightInBorders) 
       leftValueToAdd = 0; 

     if (topValueToAdd > 0) 
     { 
      if (canvasTopInBorders) 
       topValueToAdd = 0; 
     } 
     else if (topValueToAdd < 0) 
      if (canvasBottomInBorders) 
       topValueToAdd = 0; 

     Canvas.SetLeft(cvs, Canvas.GetLeft(cvs) + leftValueToAdd); 
     Canvas.SetTop(cvs,Canvas.GetTop(cvs)+topValueToAdd); 
    } 
} 
+1

+1 для предоставления кода, XAML и фотографий! Пожелать больше вопросов было так ясно. Добро пожаловать наверх. –

ответ

2

В основном вы прикрепляете события мыши к поверхности, которая масштабируется, а координаты мыши также изменяются. Silverlight спроектирован так, чтобы оставаться интерактивным при повороте, масштабировании и наклоне.

Вы хотите поместить прозрачный слой поверх, который не масштабируется, и приложите ваши методы мыши к этому слою.

Если вы оставите этот слой включенным, вам придется вычислять столкновений, но вы можете сделать это так, чтобы слой отображался только на мыши и уходил по мыши.

+0

Yeaaah, который работает ... Thaaaaanks .. как глупо я .. -_- – Zero