2017-09-26 8 views
0
<utils:ScrollViewer x:Name="ImageViewer" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Grid.Row="2"                 
             CurrentHorizontalOffset="{Binding ScrollHorizontalValue, Mode=TwoWay}" 
             CurrentVerticalOffset="{Binding ScrollVerticalValue, Mode=TwoWay}"           
             > 
        <i:Interaction.Triggers> 
         <i:EventTrigger EventName="PreviewMouseWheel"> 
          <cmd:EventToCommand Command="{Binding MouseWheelZoomCommand}" PassEventArgsToCommand="True"/> 
         </i:EventTrigger> 
         <i:EventTrigger EventName="ScrollChanged"> 
          <cmd:EventToCommand Command="{Binding ScrollChangedCommand}" PassEventArgsToCommand="True"/> 
         </i:EventTrigger> 
        </i:Interaction.Triggers> 
        <Grid Background="{StaticResource ThatchBackground}" RenderTransformOrigin="0.5,0.5"> 
         <ItemsControl ItemsSource="{Binding CanvasItems}" ItemTemplate="{StaticResource templateOfROI}"> 
          <ItemsControl.ItemsPanel> 
           <ItemsPanelTemplate> 
            <Canvas x:Name="BackPanel" 
             Width="{Binding DataContext.ImageWidth, ElementName=MainGrid}" 
             Height="{Binding DataContext.ImageHeight, ElementName=MainGrid}" 
             ClipToBounds="True"> 
             <Canvas.Background> 
              <ImageBrush x:Name="BackImage" 
                 ImageSource="{Binding DataContext.SelectedImage.Path, ElementName=MainGrid}"/> 
             </Canvas.Background> 

             <i:Interaction.Triggers> 
              <i:EventTrigger EventName="MouseRightButtonDown"> 
               <cmd:EventToCommand Command="{Binding DataContext.MouseRightCommand, ElementName=MainGrid}"/> 
              </i:EventTrigger> 
              <i:EventTrigger EventName="MouseLeftButtonDown"> 
               <cmd:EventToCommand Command="{Binding DataContext.MouseMoveStartCommand, ElementName=MainGrid}" PassEventArgsToCommand="True"/> 
              </i:EventTrigger> 
              <i:EventTrigger EventName="MouseMove"> 
               <cmd:EventToCommand Command="{Binding DataContext.MouseMovingCommand, ElementName=MainGrid}" PassEventArgsToCommand="True"/> 
              </i:EventTrigger> 
              <i:EventTrigger EventName="MouseRightButtonUp"> 
               <cmd:EventToCommand Command="{Binding DataContext.MouseMoveEndCommand, ElementName=MainGrid}"/> 
              </i:EventTrigger> 
              <i:EventTrigger EventName="MouseLeave"> 
               <cmd:EventToCommand Command="{Binding DataContext.MouseLeaveCommand, ElementName=MainGrid}"/> 
              </i:EventTrigger> 
             </i:Interaction.Triggers> 

             <Canvas.LayoutTransform> 
              <TransformGroup> 
               <ScaleTransform ScaleX="{Binding ScaleX}" 
                   ScaleY="{Binding ScaleY}"> 
               </ScaleTransform> 
             </TransformGroup> 
            </Canvas.LayoutTransform> 
           </Canvas> 
          </ItemsPanelTemplate> 
         </ItemsControl.ItemsPanel> 
        </ItemsControl> 
       </Grid> 
      </utils:ScrollViewer> 

참조 점은 캔버스를 확대/축소하기 위해 왼쪽 및 위쪽 점으로 고정됩니다. 마우스 포인터를 확대하고 축소하고 싶습니다. 어떻게 MVVM 패턴으로 만들 수 있습니까? (코드 뒤에 없음). 마우스 휠을 사용하여 캔버스를 확대 할 수 있습니다. 이미 RenderTransformOrigin, CenterX, CenterY를 사용하지만 작동하지 않습니다. 나는 내가 잘못된 접근법을했다고 생각한다. 제발 도와주세요 ..WPF 확대 캔버스 센터 마우스 위치

+1

어디 줌을 처리하는 코드이다? 예상대로 작동하지 않을 때에도 현재의 접근 방식으로 포함시켜야합니다. – grek40

답변

3

을 당신이 당신의 현재의 줌 코드를 제공하지 않았기 때문에, 여기에 마우스 위치에 확대의 일반적인 예는 다음과 같습니다

: 변환 매트릭스를 업데이트 코드와

<Grid x:Name="grid1" Background="White" MouseWheel="Grid_MouseWheel"> 
    <Grid x:Name="grid2"> 
     <Grid.RenderTransform> 
      <MatrixTransform/> 
     </Grid.RenderTransform> 
     <Rectangle Width="20" Height="20" Margin="20" VerticalAlignment="Top" HorizontalAlignment="Left" Fill="Green"/> 
    </Grid> 
</Grid> 

private void Grid_MouseWheel(object sender, MouseWheelEventArgs e) 
{ 
    var matTrans = grid2.RenderTransform as MatrixTransform; 
    var pos1 = e.GetPosition(grid1); 

    var scale = e.Delta > 0 ? 1.1 : 1/1.1; 

    var mat = matTrans.Matrix; 
    mat.ScaleAt(scale, scale, pos1.X, pos1.Y); 
    matTrans.Matrix = mat; 
    e.Handled = true; 
} 
+1

괜찮 으면 좋겠지 만 코드에 기반한 답변을 MVVM 패턴을 고수하려는 사람들을위한 'Behavior'형태로 추가했습니다. –

+0

@BradleyUffner 전혀 괜찮습니다. 다양한 좋은 해결책들이 전체적으로 도움이되고, 당신이 내 기고에 언급 한 방식에 만족할 것입니다.) – grek40

3

나는 Grek40의 코드를 사용하여 MVVM 패턴을 고수하려고하는 모든 사람을 위해 Behavior으로 변환했습니다. 만약 당신이 이것을 찬성표로 쓴다면, 그의 대답에 대해서도 찬성을 표한다. Behavior 기본 클래스에는 System.Windows.Interactivity.WPF 누 겟 패키지 (또는 다른 프레임 워크)이 필요합니다. 이 내용을 UIElement에 적용 할 수 있습니다. MatrixTransform이 자동으로 추가되므로 XAML에서 기존의 변환을 덮어 쓰지 않아도됩니다.

public class ZoomOnMouseWheel : Behavior<FrameworkElement> 
{ 
    public Key? ModifierKey { get; set; } = null; 
    public TransformMode TranformMode { get; set; } = TransformMode.Render; 

    private Transform _transform; 

    protected override void OnAttached() 
    { 
     if (TranformMode == TransformMode.Render) 
     { 
      _transform = AssociatedObject.RenderTransform = new MatrixTransform(); 
     } 
     else 
     { 
      _transform = AssociatedObject.LayoutTransform = new MatrixTransform(); 
     } 

     AssociatedObject.MouseWheel += AssociatedObject_MouseWheel; 
    } 

    protected override void OnDetaching() 
    { 
     AssociatedObject.MouseWheel -= AssociatedObject_MouseWheel; 
    } 

    private void AssociatedObject_MouseWheel(object sender, MouseWheelEventArgs e) 
    { 
     if ((!ModifierKey.HasValue || !Keyboard.IsKeyDown(ModifierKey.Value)) && ModifierKey.HasValue) 
     { 
      return; 
     } 

     if (!(_transform is MatrixTransform transform)) 
     { 
      return; 
     } 

     var pos1 = e.GetPosition(AssociatedObject); 
     var scale = e.Delta > 0 ? 1.1 : 1/1.1; 
     var mat = transform.Matrix; 
     mat.ScaleAt(scale, scale, pos1.X, pos1.Y); 
     transform.Matrix = mat; 
     e.Handled = true; 
    } 
} 

public enum TransformMode 
{ 
    Layout, 
    Render, 
} 

이처럼 사용할 수 있습니다

이 가
<Grid> 
    <interactivity:Interaction.Behaviors> 
     <behaviors:ZoomOnMouseWheel /> 
    </interactivity:Interaction.Behaviors> 
    <!--Your grid content here--> 
</Grid> 

잊지 마세요 xmlns :

xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity" 
+0

'LeftCtrl'과 같은 수정 자 키가 눌려져있을 때만 스크롤 할 수있는 기능을 추가했습니다 'ModifierKey' 속성,'TransformMode' 속성을 통해'RenderTranform' 또는'LayoutTransform'으로 변환이 수행되는지 여부를 제어 할 수있는 기능을 제공합니다. 'RenderTransform'을 기본값으로 사용하지만, scrollviewer 안에'Behavior' 엘리먼트를 놓고'LayoutTransform'으로 설정하면 확대 할 때 스크롤바를 얻을 수 있습니다. –

관련 문제